#include "upgfactory.h"

CUpgFactory::CUpgFactory()
{

}

CUpgFactory::~CUpgFactory()
{

}

SNetVersion*  CUpgFactory::analyDataDatagramVersion(SUpgHead* pUpgHead, char* pData, int iLen)
{
	if(!pUpgHead || !pData)
	{
		return 0;
	}	

	if(pUpgHead->usDataLen != iLen - sizeof(SHeartbeat) - sizeof(SUpgHead)  - 2/*CRC*/)
	{
		return 0;
	}

	// some variables
	SNetVersion* pNetVersion = 0;
	quint16 usCRC = 0;
	quint16 usCRC1 = 0;

	// Check CRC
	usCRC = CRC16((uchar*)pData, iLen - 2/*CRC*/);
	usCRC1 = 0;
	getParamFromBuffer(pData + iLen - 2/*CRC*/, usCRC1);
	if (usCRC1 == usCRC)
	{
		if (UPG_DATA_VERSION == pUpgHead->uCmdType) // 电池堆
		{
			if (pUpgHead->usDataLen == sizeof(SNetVersion))
			{
				pNetVersion = (SNetVersion*)(pData + sizeof(SHeartbeat) + sizeof(SUpgHead));				
			}			
		}		
	}

	return pNetVersion;
}

//  1 - 解析成功 - 不需要回复
//  0 - 解析成功
// -1 - 参数错误
// -2 - 数据长度不对
// -3 - CRC校验错误  
// -4 - 数据区长度不对
// -5 - 获取数据失败
// -6 - 命令号不正确
// -7 - 命令执行失败
// -999 - 其他错误
int CUpgFactory::analyDataDatagramStack(SUpgHead* pUpgHead,  CBattStack* pBattStack, char* pData, int iLen)
{
	if(!pUpgHead || !pBattStack || !pData)
	{
		return -1;
	}

	if(pUpgHead->usDataLen != iLen - sizeof(SHeartbeat) - sizeof(SUpgHead)  - 2/*CRC*/)
	{
		return -2;
	}

	// some variables
	int iRetVal = -999;	
	SNetBattStack* pNetBattStack = 0;

	quint16 usCRC = 0;
	quint16 usCRC1 = 0;

	// Check CRC
	usCRC = CRC16((uchar*)pData, iLen - 2/*CRC*/);
	usCRC1 = 0;
	getParamFromBuffer(pData + iLen - 2/*CRC*/, usCRC1);
	if (usCRC1 == usCRC)
	{
		if (UPG_DATA_STACK == pUpgHead->uCmdType) // 电池堆
		{
			if (pUpgHead->usDataLen == sizeof(SNetBattStack))
			{
				pNetBattStack = (SNetBattStack*)(pData + sizeof(SHeartbeat) + sizeof(SUpgHead));
				if(pNetBattStack)
				{
					// Data
					pBattStack->usStackState = pNetBattStack->usStackState;                
					pBattStack->usInstallBankNum = pNetBattStack->usInstallBankNum;            
					pBattStack->usBankNumInStack = pNetBattStack->usBankNumInStack;            
					pBattStack->usStackCfgInfo = pNetBattStack->usStackCfgInfo;                    
					pBattStack->usMaxBankSocNo = pNetBattStack->usMaxBankSocNo;               
					pBattStack->usMinBankSocNo = pNetBattStack->usMinBankSocNo;               
					pBattStack->usMaxBankVolNo = pNetBattStack->usMaxBankVolNo;               
					pBattStack->usMinBankVolNo = pNetBattStack->usMinBankVolNo;               
					pBattStack->usSglMaxVolBankNo = pNetBattStack->usSglMaxVolBankNo;            
					pBattStack->usSglMaxVolNoInBank = pNetBattStack->usSglMaxVolNoInBank;          
					pBattStack->usSglMinVolBankNo = pNetBattStack->usSglMinVolBankNo;            
					pBattStack->usSglMinVolNoInBank = pNetBattStack->usSglMinVolNoInBank;          
					pBattStack->usSglMaxTempBankNo = pNetBattStack->usSglMaxTempBankNo;           
					pBattStack->usSglMaxTempNoInBank = pNetBattStack->usSglMaxTempNoInBank;         
					pBattStack->usSglMinTempBankNo = pNetBattStack->usSglMinTempBankNo;            
					pBattStack->usSglMinTempNoInBank = pNetBattStack->usSglMinTempNoInBank;          
					pBattStack->usDI1 = pNetBattStack->usDI1;			           
					pBattStack->usDI2 = pNetBattStack->usDI2;	                       
					pBattStack->usDI3 = pNetBattStack->usDI3;	                        
					pBattStack->usDI4 = pNetBattStack->usDI4;	                       

					pBattStack->fStackVol = pNetBattStack->fStackVol;                   
					pBattStack->fStackCur = pNetBattStack->fStackCur;	                  
					pBattStack->fStackPower = pNetBattStack->fStackPower;                    
					pBattStack->fStackInsuRes = pNetBattStack->fStackInsuRes;                   
					pBattStack->fStackSoc = pNetBattStack->fStackSoc;                                      
					pBattStack->fStackSoh = pNetBattStack->fStackSoh;	                                       
					pBattStack->fStackChargeEQ = pNetBattStack->fStackChargeEQ;	               
					pBattStack->fStackDischargeEQ = pNetBattStack->fStackDischargeEQ;               
					pBattStack->fStackSglChargeEQ = pNetBattStack->fStackSglChargeEQ;             
					pBattStack->fStackSglDischargeEQ = pNetBattStack->fStackSglDischargeEQ;            
					pBattStack->dblStackChargeEQAdd = pNetBattStack->fStackChargeEQAdd;           
					pBattStack->dblStackDischargeEQAdd = pNetBattStack->fStackDischargeEQAdd;	       
					pBattStack->fStackSglChargeAh = pNetBattStack->fStackSglChargeAh;                          
					pBattStack->fStackSglDischargeAh = pNetBattStack->fStackSglDischargeAh;                    
					pBattStack->dblStackChargeAhAdd = pNetBattStack->fStackChargeAhAdd;                        
					pBattStack->dblStackDischargeAhAdd = pNetBattStack->fStackDischargeAhAdd;	       
					pBattStack->fSglVolDiffInStack = pNetBattStack->fSglVolDiffInStack;            
					pBattStack->fSglMaxVolInStack = pNetBattStack->fSglMaxVolInStack;             
					pBattStack->fSglMinVolInStack = pNetBattStack->fSglMinVolInStack;             
					pBattStack->fSglTempDiffInStack = pNetBattStack->fSglTempDiffInStack;            
					pBattStack->fSglMaxTempInStack = pNetBattStack->fSglMaxTempInStack;             
					pBattStack->fSglMinTempInStack = pNetBattStack->fSglMinTempInStack;             
					pBattStack->fBankSocDiff = pNetBattStack->fBankSocDiff;                   
					pBattStack->fBankSocMax = pNetBattStack->fBankSocMax;                   
					pBattStack->fBankSocMin = pNetBattStack->fBankSocMin;                  
					pBattStack->fBankVolDiff = pNetBattStack->fBankVolDiff;                
					pBattStack->fBankVolMax = pNetBattStack->fBankVolMax;                    
					pBattStack->fBankVolMin = pNetBattStack->fBankVolMin;                   
					pBattStack->fStackAllowMaxChargePower = pNetBattStack->fStackAllowMaxChargePower;       
					pBattStack->fStackAllowMaxDischargePower = pNetBattStack->fStackAllowMaxDischargePower;   
					pBattStack->fStackAllowMaxChargeCurrent = pNetBattStack->fStackAllowMaxChargeCurrent;     
					pBattStack->fStackAllowMaxDischargeCurrent = pNetBattStack->fStackAllowMaxDischargeCurrent; 

					iRetVal = 0;
				}
				else
				{
					iRetVal = -5;
				}
			}
			else
			{
				iRetVal = -4;
			}
		}
		else
		{
			iRetVal = -6;
		}
	}
	else
	{
		iRetVal = -3;
	}

	return iRetVal;
}

//  1 - 解析成功 - 不需要回复
//  0 - 解析成功
// -1 - 参数错误
// -2 - 数据长度不对
// -3 - CRC校验错误  
// -4 - 数据区长度不对
// -5 - 获取数据失败
// -6 - 命令号不正确
// -7 - 命令执行失败
// -999 - 其他错误
int CUpgFactory::analyDataDatagramBank(SUpgHead* pUpgHead, CBattBank* pBattBank, CBankAlarm* pBankAlarm, char* pData, int iLen)
{
	if(!pUpgHead || !pBattBank || !pData || !pBankAlarm)
	{
		return -1;
	}

	if(pUpgHead->usDataLen != iLen - sizeof(SHeartbeat) - sizeof(SUpgHead) - 2/*CRC*/)
	{
		return -2;
	}

	// some variables
	int iRetVal = -999;	
	SNetBattBankAlarm* pNetBattBankAlarm = 0;
	SNetBattBankSglOther* pNetBattBankSglOther = 0;

	float* pFVal = 0;
	quint16 usCRC = 0;
	quint16 usCRC1 = 0;

	// Check CRC
	usCRC = CRC16((uchar*)pData, iLen - 2/*CRC*/);
	usCRC1 = 0;
	getParamFromBuffer(pData + iLen - 2/*CRC*/, usCRC1);
	if (usCRC1 == usCRC)
	{
		if (UPG_DATA_BANK_ALARM == pUpgHead->uCmdType)  // 电池组数据 - 告警信息 
		{
			if (pUpgHead->usDataLen == sizeof(SNetBattBankAlarm))
			{
				pNetBattBankAlarm = (SNetBattBankAlarm*)(pData + sizeof(SHeartbeat) + sizeof(SUpgHead));
				if (pNetBattBankAlarm)
				{
					pBattBank->aBankVolUpLimitWarn = pNetBattBankAlarm->aBankVolUpLimitWarn;   
					pBattBank->aBankVolDownLimitWarn = pNetBattBankAlarm->aBankVolDownLimitWarn;     
					pBattBank->aChgCurUpLimitWarn = pNetBattBankAlarm->aChgCurUpLimitWarn;		
					pBattBank->aDchgCurUpLimitWarn = pNetBattBankAlarm->aDchgCurUpLimitWarn;		
					pBattBank->aSglVolUpLimitWarn = pNetBattBankAlarm->aSglVolUpLimitWarn;	    
					pBattBank->aSglVolDownLimitWarn = pNetBattBankAlarm->aSglVolDownLimitWarn;	  
					pBattBank->aChgTempUpLimitWarn = pNetBattBankAlarm->aChgTempUpLimitWarn;	    
					pBattBank->aChgTempDownLimitWarn = pNetBattBankAlarm->aChgTempDownLimitWarn;	    
					pBattBank->aDchgTempUpLimitWarn = pNetBattBankAlarm->aDchgTempUpLimitWarn;	    
					pBattBank->aDchgTempDownLimitWarn = pNetBattBankAlarm->aDchgTempDownLimitWarn;	
					pBattBank->aSglTempUpLimitWarn = pNetBattBankAlarm->aSglTempUpLimitWarn;	    
					pBattBank->aSglTempDownLimitWarn = pNetBattBankAlarm->aSglTempDownLimitWarn;	    
					pBattBank->aEnvTempUpLimitWarn = pNetBattBankAlarm->aEnvTempUpLimitWarn;		
					pBattBank->aEnvTempDownLimitWarn = pNetBattBankAlarm->aEnvTempDownLimitWarn;	   
					pBattBank->aPowerLineTempUpLimitWarn = pNetBattBankAlarm->aPowerLineTempUpLimitWarn;	 
					pBattBank->aBankSocUpLimitWarn = pNetBattBankAlarm->aBankSocUpLimitWarn;	    
					pBattBank->aBankSocDownLimitWarn = pNetBattBankAlarm->aBankSocDownLimitWarn;	    
					pBattBank->aPosResDownLimitWarn = pNetBattBankAlarm->aPosResDownLimitWarn;		
					pBattBank->aNegResDownLimitWarn = pNetBattBankAlarm->aNegResDownLimitWarn;		
					pBattBank->aPackVolDiffUpLimitWarn = pNetBattBankAlarm->aPackVolDiffUpLimitWarn;	
					pBattBank->aPackTempDiffUpLimitWarn = pNetBattBankAlarm->aPackTempDiffUpLimitWarn;	
					pBattBank->aBankVolUpLimitAlarm = pNetBattBankAlarm->aBankVolUpLimitAlarm;	   
					pBattBank->aBankVolDownLimitAlarm = pNetBattBankAlarm->aBankVolDownLimitAlarm;     
					pBattBank->aChgCurUpLimitAlarm = pNetBattBankAlarm->aChgCurUpLimitAlarm;		
					pBattBank->aDchgCurUpLimitAlarm = pNetBattBankAlarm->aDchgCurUpLimitAlarm;		
					pBattBank->aSglVolUpLimitAlarm = pNetBattBankAlarm->aSglVolUpLimitAlarm;	     
					pBattBank->aSglVolDownLimitAlarm = pNetBattBankAlarm->aSglVolDownLimitAlarm;	    
					pBattBank->aChgTempUpLimitAlarm = pNetBattBankAlarm->aChgTempUpLimitAlarm;	     
					pBattBank->aChgTempDownLimitAlarm = pNetBattBankAlarm->aChgTempDownLimitAlarm;	 
					pBattBank->aDchgTempUpLimitAlarm = pNetBattBankAlarm->aDchgTempUpLimitAlarm;	    
					pBattBank->aDchgTempDownLimitAlarm = pNetBattBankAlarm->aDchgTempDownLimitAlarm;	
					pBattBank->aSglTempUpLimitAlarm = pNetBattBankAlarm->aSglTempUpLimitAlarm;	     
					pBattBank->aSglTempDownLimitAlarm = pNetBattBankAlarm->aSglTempDownLimitAlarm;	
					pBattBank->aEnvTempUpLimitAlarm = pNetBattBankAlarm->aEnvTempUpLimitAlarm;		
					pBattBank->aEnvTempDownLimitAlarm = pNetBattBankAlarm->aEnvTempDownLimitAlarm;	
					pBattBank->aPowerLineTempUpLimitAlarm = pNetBattBankAlarm->aPowerLineTempUpLimitAlarm; 
					pBattBank->aBankSocUpLimitAlarm = pNetBattBankAlarm->aBankSocUpLimitAlarm;	    
					pBattBank->aBankSocDownLimitAlarm = pNetBattBankAlarm->aBankSocDownLimitAlarm;	
					pBattBank->aPosResDownLimitAlarm = pNetBattBankAlarm->aPosResDownLimitAlarm;		
					pBattBank->aNegResDownLimitAlarm = pNetBattBankAlarm->aNegResDownLimitAlarm;		
					pBattBank->aPackVolDiffUpLimitAlarm = pNetBattBankAlarm->aPackVolDiffUpLimitAlarm;	
					pBattBank->aPackTempDiffUpLimitAlarm = pNetBattBankAlarm->aPackTempDiffUpLimitAlarm;	
					pBattBank->aBankVolUpLimitProt = pNetBattBankAlarm->aBankVolUpLimitProt;	   
					pBattBank->aBankVolDownLimitProt = pNetBattBankAlarm->aBankVolDownLimitProt;     
					pBattBank->aChgCurUpLimitProt = pNetBattBankAlarm->aChgCurUpLimitProt;		 
					pBattBank->aDchgCurUpLimitProt = pNetBattBankAlarm->aDchgCurUpLimitProt;		
					pBattBank->aSglVolUpLimitProt = pNetBattBankAlarm->aSglVolUpLimitProt;	   
					pBattBank->aSglVolDownLimitProt = pNetBattBankAlarm->aSglVolDownLimitProt;	    
					pBattBank->aChgTempUpLimitProt = pNetBattBankAlarm->aChgTempUpLimitProt;	   	
					pBattBank->aChgTempDownLimitProt = pNetBattBankAlarm->aChgTempDownLimitProt;	    
					pBattBank->aDchgTempUpLimitProt = pNetBattBankAlarm->aDchgTempUpLimitProt;	     
					pBattBank->aDchgTempDownLimitProt = pNetBattBankAlarm->aDchgTempDownLimitProt;	
					pBattBank->aSglTempUpLimitProt = pNetBattBankAlarm->aSglTempUpLimitProt;	     
					pBattBank->aSglTempDownLimitProt = pNetBattBankAlarm->aSglTempDownLimitProt;	   
					pBattBank->aEnvTempUpLimitProt = pNetBattBankAlarm->aEnvTempUpLimitProt;		
					pBattBank->aEnvTempDownLimitProt = pNetBattBankAlarm->aEnvTempDownLimitProt;	  
					pBattBank->aPowerLineTempUpLimitProt = pNetBattBankAlarm->aPowerLineTempUpLimitProt;	 
					pBattBank->aBankSocUpLimitProt = pNetBattBankAlarm->aBankSocUpLimitProt;	    
					pBattBank->aBankSocDownLimitProt = pNetBattBankAlarm->aBankSocDownLimitProt;	     
					pBattBank->aPosResDownLimitProt = pNetBattBankAlarm->aPosResDownLimitProt;		
					pBattBank->aNegResDownLimitProt = pNetBattBankAlarm->aNegResDownLimitProt;		
					pBattBank->aPackVolDiffUpLimitProt = pNetBattBankAlarm->aPackVolDiffUpLimitProt;
					pBattBank->aPackTempDiffUpLimitProt = pNetBattBankAlarm->aPackTempDiffUpLimitProt;	
					pBattBank->aSglTempRise = pNetBattBankAlarm->aSglTempRise;	          
					pBattBank->aPowerLineTempRise = pNetBattBankAlarm->aPowerLineTempRise;	   
					pBattBank->aBMUConnFault = pNetBattBankAlarm->aBMUConnFault;		         
					pBattBank->aBCMUConnFault = pNetBattBankAlarm->aBCMUConnFault;		   
					pBattBank->aSglVolWireFault = pNetBattBankAlarm->aSglVolWireFault;        
					pBattBank->aBankVolWireFault = pNetBattBankAlarm->aBankVolWireFault;         
					pBattBank->aCurWireFault = pNetBattBankAlarm->aCurWireFault;            
					pBattBank->aTempWireBreak = pNetBattBankAlarm->aTempWireBreak;             
					pBattBank->aTempShortCircuit = pNetBattBankAlarm->aTempShortCircuit;          
					pBattBank->aBMSFault = pNetBattBankAlarm->aBMSFault;                 
					pBattBank->aSglVolInvalid = pNetBattBankAlarm->aSglVolInvalid;           
					pBattBank->aSglTempInvalid = pNetBattBankAlarm->aSglTempInvalid;           
					pBattBank->aBankVolInvalid = pNetBattBankAlarm->aBankVolInvalid;    
     
					iRetVal = 0;					
				}
				else
				{
					iRetVal = -5;
				}
			}
			else
			{
				iRetVal = -4;
			}
		}
		else if (UPG_DATA_BANK_SGL_VOL1 == pUpgHead->uCmdType)  // 单体电压   1 - 100
		{
			if (pUpgHead->usDataLen == 4 * 100)
			{
				pFVal = (float*)(pData + sizeof(SHeartbeat) + sizeof(SUpgHead));

				for (int i = 0; i < 100; ++i)
				{
					pBattBank->fSglVol[i] = *pFVal;
					++pFVal;
				}

				iRetVal = 0;
			}
			else
			{
				iRetVal = -4;
			}			
		}
		else if (UPG_DATA_BANK_SGL_VOL2 == pUpgHead->uCmdType)  // 单体电压 101 - 200
		{
			if (pUpgHead->usDataLen == 4 * 100)
			{
				pFVal = (float*)(pData + sizeof(SHeartbeat) + sizeof(SUpgHead));

				for (int i = 0; i < 100; ++i)
				{
					pBattBank->fSglVol[i + 100] = *pFVal;
					++pFVal;
				}

				iRetVal = 0;
			}
			else
			{
				iRetVal = -4;
			}	
		}
		else if (UPG_DATA_BANK_SGL_VOL3 == pUpgHead->uCmdType)  // 单体电压 201 - 300
		{
			if (pUpgHead->usDataLen == 4 * 100)
			{
				pFVal = (float*)(pData + sizeof(SHeartbeat) + sizeof(SUpgHead));

				for (int i = 0; i < 100; ++i)
				{
					pBattBank->fSglVol[i + 200] = *pFVal;
					++pFVal;
				}

				iRetVal = 0;
			}
			else
			{
				iRetVal = -4;
			}	
		}
		else if (UPG_DATA_BANK_SGL_VOL4 == pUpgHead->uCmdType)  // 单体电压 301 - 400
		{
			if (pUpgHead->usDataLen == 4 * 100)
			{
				pFVal = (float*)(pData + sizeof(SHeartbeat) + sizeof(SUpgHead));

				for (int i = 0; i < 100; ++i)
				{
					pBattBank->fSglVol[i + 300] = *pFVal;
					++pFVal;
				}

				iRetVal = 0;
			}
			else
			{
				iRetVal = -4;
			}	
		}
		else if (UPG_DATA_BANK_SGL_TEMP1 == pUpgHead->uCmdType)  // 单体温度   1 - 100
		{
			if (pUpgHead->usDataLen == 4 * 100)
			{
				pFVal = (float*)(pData + sizeof(SHeartbeat) + sizeof(SUpgHead));

				for (int i = 0; i < 100; ++i)
				{
					pBattBank->fSglTemp[i] = *pFVal;
					++pFVal;
				}

				iRetVal = 0;
			}
			else
			{
				iRetVal = -4;
			}	
		}
		else if (UPG_DATA_BANK_SGL_TEMP2 == pUpgHead->uCmdType)  // 单体温度 101 - 200
		{
			if (pUpgHead->usDataLen == 4 * 100)
			{
				pFVal = (float*)(pData + sizeof(SHeartbeat) + sizeof(SUpgHead));

				for (int i = 0; i < 100; ++i)
				{
					pBattBank->fSglTemp[i + 100] = *pFVal;
					++pFVal;
				}

				iRetVal = 0;
			}
			else
			{
				iRetVal = -4;
			}	
		}
		else if (UPG_DATA_BANK_SGL_TEMP3 == pUpgHead->uCmdType)  // 单体温度 201 - 300
		{
			if (pUpgHead->usDataLen == 4 * 100)
			{
				pFVal = (float*)(pData + sizeof(SHeartbeat) + sizeof(SUpgHead));

				for (int i = 0; i < 100; ++i)
				{
					pBattBank->fSglTemp[i + 200] = *pFVal;
					++pFVal;
				}

				iRetVal = 0;
			}
			else
			{
				iRetVal = -4;
			}	
		}	
		else if (UPG_DATA_BANK_SGL_TEMP4 == pUpgHead->uCmdType)  // 单体温度 301 - 400
		{
			if (pUpgHead->usDataLen == 4 * 100)
			{
				pFVal = (float*)(pData + sizeof(SHeartbeat) + sizeof(SUpgHead));

				for (int i = 0; i < 100; ++i)
				{
					pBattBank->fSglTemp[i + 300] = *pFVal;
					++pFVal;
				}

				iRetVal = 0;
			}
			else
			{
				iRetVal = -4;
			}	
		}
		else if (UPG_DATA_BANK_SGL_SOC1 == pUpgHead->uCmdType)  // 单体Soc   1 - 100
		{
			if (pUpgHead->usDataLen == 4 * 100)
			{
				pFVal = (float*)(pData + sizeof(SHeartbeat) + sizeof(SUpgHead));

				for (int i = 0; i < 100; ++i)
				{
					pBattBank->fSglSoc[i] = *pFVal;
					++pFVal;
				}

				iRetVal = 0;
			}
			else
			{
				iRetVal = -4;
			}	
		}
		else if (UPG_DATA_BANK_SGL_SOC2 == pUpgHead->uCmdType)  // 单体Soc 101 - 200
		{
			if (pUpgHead->usDataLen == 4 * 100)
			{
				pFVal = (float*)(pData + sizeof(SHeartbeat) + sizeof(SUpgHead));

				for (int i = 0; i < 100; ++i)
				{
					pBattBank->fSglSoc[i + 100] = *pFVal;
					++pFVal;
				}

				iRetVal = 0;
			}
			else
			{
				iRetVal = -4;
			}	
		}
		else if (UPG_DATA_BANK_SGL_SOC3 == pUpgHead->uCmdType)  // 单体Soc 201 - 300
		{
			if (pUpgHead->usDataLen == 4 * 100)
			{
				pFVal = (float*)(pData + sizeof(SHeartbeat) + sizeof(SUpgHead));

				for (int i = 0; i < 100; ++i)
				{
					pBattBank->fSglSoc[i + 200] = *pFVal;
					++pFVal;
				}

				iRetVal = 0;
			}
			else
			{
				iRetVal = -4;
			}	
		}
		else if (UPG_DATA_BANK_SGL_SOC4 == pUpgHead->uCmdType)  // 单体Soc 301 - 400
		{
			if (pUpgHead->usDataLen == 4 * 100)
			{
				pFVal = (float*)(pData + sizeof(SHeartbeat) + sizeof(SUpgHead));

				for (int i = 0; i < 100; ++i)
				{
					pBattBank->fSglSoc[i + 300] = *pFVal;
					++pFVal;
				}

				iRetVal = 0;
			}
			else
			{
				iRetVal = -4;
			}	
		}
		else if (UPG_DATA_BANK_SGL_RES1 == pUpgHead->uCmdType)  // 单体内阻   1 - 100
		{
			if (pUpgHead->usDataLen == 4 * 100)
			{
				pFVal = (float*)(pData + sizeof(SHeartbeat) + sizeof(SUpgHead));

				for (int i = 0; i < 100; ++i)
				{
					pBattBank->fSglRes[i] = *pFVal;
					++pFVal;
				}

				iRetVal = 0;
			}
			else
			{
				iRetVal = -4;
			}	
		}
		else if (UPG_DATA_BANK_SGL_RES2 == pUpgHead->uCmdType)  // 单体内阻 101 - 200
		{
			if (pUpgHead->usDataLen == 4 * 100)
			{
				pFVal = (float*)(pData + sizeof(SHeartbeat) + sizeof(SUpgHead));

				for (int i = 0; i < 100; ++i)
				{
					pBattBank->fSglRes[i + 100] = *pFVal;
					++pFVal;
				}

				iRetVal = 0;
			}
			else
			{
				iRetVal = -4;
			}	
		}
		else if (UPG_DATA_BANK_SGL_RES3 == pUpgHead->uCmdType)  // 单体内阻 201 - 300
		{
			if (pUpgHead->usDataLen == 4 * 100)
			{
				pFVal = (float*)(pData + sizeof(SHeartbeat) + sizeof(SUpgHead));

				for (int i = 0; i < 100; ++i)
				{
					pBattBank->fSglRes[i + 200] = *pFVal;
					++pFVal;
				}

				iRetVal = 0;
			}
			else
			{
				iRetVal = -4;
			}	
		}
		else if (UPG_DATA_BANK_SGL_RES4 == pUpgHead->uCmdType)  // 单体内阻 301 - 400
		{
			if (pUpgHead->usDataLen == 4 * 100)
			{
				pFVal = (float*)(pData + sizeof(SHeartbeat) + sizeof(SUpgHead));

				for (int i = 0; i < 100; ++i)
				{
					pBattBank->fSglRes[i + 300] = *pFVal;
					++pFVal;
				}

				iRetVal = 0;
			}
			else
			{
				iRetVal = -4;
			}	
		}
		else if (UPG_DATA_BANK_SGL_SOH1 == pUpgHead->uCmdType)  // 单体Soh   1 - 100
		{
			if (pUpgHead->usDataLen == 4 * 100)
			{
				pFVal = (float*)(pData + sizeof(SHeartbeat) + sizeof(SUpgHead));

				for (int i = 0; i < 100; ++i)
				{
					pBattBank->fSglSoh[i] = *pFVal;
					++pFVal;
				}

				iRetVal = 0;
			}
			else
			{
				iRetVal = -4;
			}	
		}
		else if (UPG_DATA_BANK_SGL_SOH2 == pUpgHead->uCmdType)  // 单体Soh 101 - 200
		{
			if (pUpgHead->usDataLen == 4 * 100)
			{
				pFVal = (float*)(pData + sizeof(SHeartbeat) + sizeof(SUpgHead));

				for (int i = 0; i < 100; ++i)
				{
					pBattBank->fSglSoh[i + 100] = *pFVal;
					++pFVal;
				}

				iRetVal = 0;
			}
			else
			{
				iRetVal = -4;
			}	
		}
		else if (UPG_DATA_BANK_SGL_SOH3 == pUpgHead->uCmdType)  // 单体Soh 201 - 300
		{
			if (pUpgHead->usDataLen == 4 * 100)
			{
				pFVal = (float*)(pData + sizeof(SHeartbeat) + sizeof(SUpgHead));

				for (int i = 0; i < 100; ++i)
				{
					pBattBank->fSglSoh[i + 200] = *pFVal;
					++pFVal;
				}

				iRetVal = 0;
			}
			else
			{
				iRetVal = -4;
			}	
		}
		else if (UPG_DATA_BANK_SGL_SOH4 == pUpgHead->uCmdType)  // 单体Soh 301 - 400
		{
			if (pUpgHead->usDataLen == 4 * 100)
			{
				pFVal = (float*)(pData + sizeof(SHeartbeat) + sizeof(SUpgHead));

				for (int i = 0; i < 100; ++i)
				{
					pBattBank->fSglSoh[i + 300] = *pFVal;
					++pFVal;
				}

				iRetVal = 0;
			}
			else
			{
				iRetVal = -4;
			}	
		}
		else if (UPG_DATA_BANK_OTHER == pUpgHead->uCmdType)  // 其他电池组数据
		{
			if (pUpgHead->usDataLen == sizeof(SNetBattBankSglOther))
			{
				pNetBattBankSglOther = (SNetBattBankSglOther*)(pData + sizeof(SHeartbeat) + sizeof(SUpgHead));
				if (pNetBattBankSglOther)
				{
					// Data
					pBattBank->usBankState = pNetBattBankSglOther->usBankState;          
					pBattBank->usBankChgDchgState = pNetBattBankSglOther->usBankChgDchgState;	
					pBattBank->usCellNumInBank = pNetBattBankSglOther->usCellNumInBank;       
					pBattBank->usTempNumInBank = pNetBattBankSglOther->usTempNumInBank;      
					pBattBank->usPackNumInBank = pNetBattBankSglOther->usPackNumInBank;        
					pBattBank->usChgNum = pNetBattBankSglOther->usChgNum;	           
					pBattBank->usDchgNum = pNetBattBankSglOther->usDchgNum;	            
					pBattBank->usSglMaxVolNo = pNetBattBankSglOther->usSglMaxVolNo;        
					pBattBank->usSglMinVolNo = pNetBattBankSglOther->usSglMinVolNo;         
					pBattBank->usSglMaxTempNo = pNetBattBankSglOther->usSglMaxTempNo;      
					pBattBank->usSglMinTempNo = pNetBattBankSglOther->usSglMinTempNo;         
					pBattBank->usSglMaxResNo = pNetBattBankSglOther->usSglMaxResNo;       
					pBattBank->usSglMinResNo = pNetBattBankSglOther->usSglMinResNo;        
					pBattBank->usSglMaxSocNo = pNetBattBankSglOther->usSglMaxSocNo;          
					pBattBank->usSglMinSocNo = pNetBattBankSglOther->usSglMinSocNo;       
					pBattBank->usSglMaxSohNo = pNetBattBankSglOther->usSglMaxSohNo;        
					pBattBank->usSglMinSohNo = pNetBattBankSglOther->usSglMinSohNo;       	
					pBattBank->usDI1 = pNetBattBankSglOther->usDI1;   			
					pBattBank->usDI2 = pNetBattBankSglOther->usDI2;	                
					pBattBank->usDI3 = pNetBattBankSglOther->usDI3;	                
					pBattBank->usDI4 = pNetBattBankSglOther->usDI4;	               
					pBattBank->usDI5 = pNetBattBankSglOther->usDI5;	               
					pBattBank->usDI6 = pNetBattBankSglOther->usDI6;	                

					pBattBank->fBankVol = pNetBattBankSglOther->fBankVol;	           
					pBattBank->fBankCur = pNetBattBankSglOther->fBankCur;	           
					pBattBank->fBankPower = pNetBattBankSglOther->fBankPower;              
					pBattBank->fBankInsuRes = pNetBattBankSglOther->fBankInsuRes;            
					pBattBank->fBankSoc = pNetBattBankSglOther->fBankSoc;              
					pBattBank->fBankSoh = pNetBattBankSglOther->fBankSoh;             
					pBattBank->fEnvTemp = pNetBattBankSglOther->fEnvTemp;	          
					pBattBank->fPosRes = pNetBattBankSglOther->fPosRes;	              
					pBattBank->fNegRes = pNetBattBankSglOther->fNegRes;                 
					pBattBank->fBankChargeEQ = pNetBattBankSglOther->fBankChargeEQ;	        
					pBattBank->fBankDischargeEQ = pNetBattBankSglOther->fBankDischargeEQ;	   
					pBattBank->fBankSglChargeEQ = pNetBattBankSglOther->fBankSglChargeEQ;    	
					pBattBank->fBankSglDischargeEQ = pNetBattBankSglOther->fBankSglDischargeEQ;	   
					pBattBank->dblBankChargeEQAdd = pNetBattBankSglOther->fBankChargeEQAdd;	   
					pBattBank->dblBankDischargeEQAdd = pNetBattBankSglOther->fBankDischargeEQAdd;    
					pBattBank->fBankSglChargeAh = pNetBattBankSglOther->fBankSglChargeAh;    	   
					pBattBank->fBankSglDischargeAh = pNetBattBankSglOther->fBankSglDischargeAh;	  
					pBattBank->dblBankChargeAhAdd = pNetBattBankSglOther->fBankChargeAhAdd;	     	           
					pBattBank->dblBankDischargeAhAdd = pNetBattBankSglOther->fBankDischargeAhAdd;             
					pBattBank->fSglVolDiffInBank = pNetBattBankSglOther->fSglVolDiffInBank;        
					pBattBank->fSglAvgVol = pNetBattBankSglOther->fSglAvgVol;             
					pBattBank->fSglMaxVol = pNetBattBankSglOther->fSglMaxVol;              
					pBattBank->fSglMinVol = pNetBattBankSglOther->fSglMinVol;	            
					pBattBank->fSglTempDiffInBank = pNetBattBankSglOther->fSglTempDiffInBank;      		
					pBattBank->fSglAvgTemp = pNetBattBankSglOther->fSglAvgTemp;	            
					pBattBank->fSglMaxTemp = pNetBattBankSglOther->fSglMaxTemp;              	
					pBattBank->fSglMinTemp = pNetBattBankSglOther->fSglMinTemp;             	
					pBattBank->fSglAvgRes = pNetBattBankSglOther->fSglAvgRes;               
					pBattBank->fSglMaxRes = pNetBattBankSglOther->fSglMaxRes;              
					pBattBank->fSglMinRes = pNetBattBankSglOther->fSglMinRes;             
					pBattBank->fSglAvgSoc = pNetBattBankSglOther->fSglAvgSoc;	           
					pBattBank->fSglMaxSoc = pNetBattBankSglOther->fSglMaxSoc;           
					pBattBank->fSglMinSoc = pNetBattBankSglOther->fSglMinSoc;              	
					pBattBank->fSglAvgSoh = pNetBattBankSglOther->fSglAvgSoh;              
					pBattBank->fSglMaxSoh = pNetBattBankSglOther->fSglMaxSoh;             
					pBattBank->fSglMinSoh = pNetBattBankSglOther->fSglMinSoh;              	
					pBattBank->fBankAllowMaxChargePower = pNetBattBankSglOther->fBankAllowMaxChargePower;    
					pBattBank->fBankAllowMaxDischargePower = pNetBattBankSglOther->fBankAllowMaxDischargePower;  
					pBattBank->fBankAllowMaxChargeCurrent = pNetBattBankSglOther->fBankAllowMaxChargeCurrent;    
					pBattBank->fBankAllowMaxDischargeCurrent = pNetBattBankSglOther->fBankAllowMaxDischargeCurrent; 

					iRetVal = 0;
				}
				else
				{
					iRetVal = -5;
				}				
			}
			else
			{
				iRetVal = -4;
			}
		}
		else if (UPG_DATA_WARN_PARAM == pUpgHead->uCmdType)  // 读取预警参数
		{
			if (pUpgHead->usDataLen == 4 * 12)
			{
				pFVal = (float*)(pData + sizeof(SHeartbeat) + sizeof(SUpgHead));

				pBankAlarm->param.fBankVolUpLimitWarn = *pFVal;
				++pFVal;
				pBankAlarm->param.fBankVolDownLimitWarn = *pFVal;
				++pFVal;
				pBankAlarm->param.fChargeCurUpLimitWarn = *pFVal;
				++pFVal;
				pBankAlarm->param.fDischargeCurUpLimitWarn = *pFVal;
				++pFVal;
				pBankAlarm->param.fSglVolUpLimitWarn = *pFVal;
				++pFVal;
				pBankAlarm->param.fSglVolDownLimitWarn = *pFVal;
				++pFVal;
				pBankAlarm->param.fChargeSglTempUpLimitWarn = *pFVal;
				++pFVal;
				pBankAlarm->param.fChargeSglTempDownLimitWarn = *pFVal;
				++pFVal;
				pBankAlarm->param.fDchargeSglTempUpLimitWarn = *pFVal;
				++pFVal;
				pBankAlarm->param.fDchargeSglTempDownLimitWarn = *pFVal;
				++pFVal;
				pBankAlarm->param.fBankSocUpLimitWarn = *pFVal;
				++pFVal;
				pBankAlarm->param.fBankSocDownLimitWarn = *pFVal;	
				++pFVal;

				iRetVal = 0;
			}
			else
			{
				iRetVal = -4;
			}		
		}
		else if (UPG_DATA_ALARM_PARAM == pUpgHead->uCmdType)  // 读取告警参数
		{
			if (pUpgHead->usDataLen == 4 * 12)
			{
				pFVal = (float*)(pData + sizeof(SHeartbeat) + sizeof(SUpgHead));

				pBankAlarm->param.fBankVolUpLimitAlarm = *pFVal;
				++pFVal;
				pBankAlarm->param.fBankVolDownLimitAlarm = *pFVal;
				++pFVal;
				pBankAlarm->param.fChargeCurUpLimitAlarm = *pFVal;
				++pFVal;
				pBankAlarm->param.fDischargeCurUpLimitAlarm = *pFVal;
				++pFVal;
				pBankAlarm->param.fSglVolUpLimitAlarm = *pFVal;
				++pFVal;
				pBankAlarm->param.fSglVolDownLimitAlarm = *pFVal;
				++pFVal;
				pBankAlarm->param.fChargeSglTempUpLimitAlarm = *pFVal;
				++pFVal;
				pBankAlarm->param.fChargeSglTempDownLimitAlarm = *pFVal;
				++pFVal;
				pBankAlarm->param.fDchargeSglTempUpLimitAlarm = *pFVal;
				++pFVal;
				pBankAlarm->param.fDchargeSglTempDownLimitAlarm = *pFVal;
				++pFVal;
				pBankAlarm->param.fBankSocUpLimitAlarm = *pFVal;
				++pFVal;
				pBankAlarm->param.fBankSocDownLimitAlarm = *pFVal;
				++pFVal;

				iRetVal = 0;
			}
			else
			{
				iRetVal = -4;
			}		
		}
		else if (UPG_DATA_PROT_PARAM == pUpgHead->uCmdType)  // 读取保护参数
		{
			if (pUpgHead->usDataLen == 4 * 12)
			{
				pFVal = (float*)(pData + sizeof(SHeartbeat) + sizeof(SUpgHead));
			
				pBankAlarm->param.fBankVolUpLimitProt = *pFVal;
				++pFVal;
				pBankAlarm->param.fBankVolDownLimitProt = *pFVal;
				++pFVal;
				pBankAlarm->param.fChargeCurUpLimitProt = *pFVal;
				++pFVal;
				pBankAlarm->param.fDischargeCurUpLimitProt = *pFVal;
				++pFVal;
				pBankAlarm->param.fSglVolUpLimitProt = *pFVal;
				++pFVal;
				pBankAlarm->param.fSglVolDownLimitProt = *pFVal;
				++pFVal;
				pBankAlarm->param.fChargeSglTempUpLimitProt = *pFVal;
				++pFVal;
				pBankAlarm->param.fChargeSglTempDownLimitProt = *pFVal;
				++pFVal;
				pBankAlarm->param.fDchargeSglTempUpLimitProt = *pFVal;
				++pFVal;
				pBankAlarm->param.fDchargeSglTempDownLimitProt = *pFVal;	
				++pFVal;
				pBankAlarm->param.fBankSocUpLimitProt = *pFVal;
				++pFVal;
				pBankAlarm->param.fBankSocDownLimitProt = *pFVal;
				++pFVal;

				iRetVal = 0;
			}
			else
			{
				iRetVal = -4;
			}
		}
		else if (UPG_CMD_SET_WARN_PARAM == pUpgHead->uCmdType)  // 设置预警参数
		{
			if (pUpgHead->usDataLen != 4)
			{
				iRetVal = -7;
			}
			else
			{
				iRetVal = 1;  // 不需要回复
			}
		}
		else if (UPG_CMD_SET_ALARM_PARAM == pUpgHead->uCmdType)  // 设置告警参数
		{
			if (pUpgHead->usDataLen != 4)
			{
				iRetVal = -7;
			}
			else
			{
				iRetVal = 1;  // 不需要回复
			}
		}
		else if (UPG_CMD_SET_PROT_PARAM == pUpgHead->uCmdType)  // 设置保护参数
		{
			if (pUpgHead->usDataLen != 4)
			{
				iRetVal = -7;
			}
			else
			{
				iRetVal = 1;  // 不需要回复
			}
		}
		else
		{
			iRetVal = -6;
		}
	}
	else
	{
		iRetVal = -3;
	}

	return iRetVal;
}

int CUpgFactory::prepareExcepDatagram(char* pDataBuf, SHeartbeat* pHeartbeat, SUpgHead* pUpgHead, int iErrCode)
{
	if (!pDataBuf || !pHeartbeat || !pUpgHead)
	{
		return -1;
	}

	memcpy(pDataBuf, (char*)pHeartbeat, sizeof(SHeartbeat));

	pUpgHead->usDataLen = 4;
	memcpy(pDataBuf + sizeof(SHeartbeat), (char*)pUpgHead, sizeof(SUpgHead));
	memcpy(pDataBuf + sizeof(SHeartbeat) + sizeof(SUpgHead), (char*)&iErrCode, sizeof(int));

	// CRC
	addCRC2Buffer((unsigned char *)pDataBuf, sizeof(SHeartbeat) + sizeof(SUpgHead) + sizeof(int));

	return sizeof(int) + sizeof(SHeartbeat) + sizeof(SUpgHead) + 2/*CRC*/;
}

// >= 0 OK 
// -1 参数错误 
// -2 长度不足
int CUpgFactory::prepareDatagramStack(SHeartbeat* pHeartbeat, CBattStack* pBattStack, char* pDataBuf)
{
	if (0 == pHeartbeat || 0 == pBattStack || 0 == pDataBuf)
	{
		return -1;
	}

	// some variables Hearbeat Head Data CRC
	SUpgHead* pUpgHead = 0;
	SNetBattStack* pNetBattStack = 0;

	if(sizeof(SHeartbeat) + sizeof(SUpgHead) + sizeof(SNetBattStack) + 2 /*CRC*/ > SNED_BUFFER_LENGHT)
	{
		return -2;
	}

	// Head
	memset(pDataBuf, 0, SNED_BUFFER_LENGHT);
	memcpy(pDataBuf, (char*)pHeartbeat, sizeof(SHeartbeat));

	pUpgHead = (SUpgHead*)(pDataBuf + sizeof(SHeartbeat));
	pNetBattStack = (SNetBattStack*)(pDataBuf + sizeof(SHeartbeat) + sizeof(SUpgHead));
	
	pUpgHead->uCmdType = UPG_DATA_STACK;
	pUpgHead->uModbusAddrBg = 1;
	pUpgHead->usDataLen = sizeof(SNetBattStack);

	// Data
	pNetBattStack->usStackState = pBattStack->usStackState;                
	pNetBattStack->usInstallBankNum = pBattStack->usInstallBankNum;            
	pNetBattStack->usBankNumInStack = pBattStack->usBankNumInStack;            
	pNetBattStack->usStackCfgInfo = pBattStack->usStackCfgInfo;                    
	pNetBattStack->usMaxBankSocNo = pBattStack->usMaxBankSocNo;               
	pNetBattStack->usMinBankSocNo = pBattStack->usMinBankSocNo;               
	pNetBattStack->usMaxBankVolNo = pBattStack->usMaxBankVolNo;               
	pNetBattStack->usMinBankVolNo = pBattStack->usMinBankVolNo;               
	pNetBattStack->usSglMaxVolBankNo = pBattStack->usSglMaxVolBankNo;            
	pNetBattStack->usSglMaxVolNoInBank = pBattStack->usSglMaxVolNoInBank;          
	pNetBattStack->usSglMinVolBankNo = pBattStack->usSglMinVolBankNo;            
	pNetBattStack->usSglMinVolNoInBank = pBattStack->usSglMinVolNoInBank;          
	pNetBattStack->usSglMaxTempBankNo = pBattStack->usSglMaxTempBankNo;           
	pNetBattStack->usSglMaxTempNoInBank = pBattStack->usSglMaxTempNoInBank;         
	pNetBattStack->usSglMinTempBankNo = pBattStack->usSglMinTempBankNo;            
	pNetBattStack->usSglMinTempNoInBank = pBattStack->usSglMinTempNoInBank;          
	pNetBattStack->usDI1 = pBattStack->usDI1;			           
	pNetBattStack->usDI2 = pBattStack->usDI2;	                       
	pNetBattStack->usDI3 = pBattStack->usDI3;	                        
	pNetBattStack->usDI4 = pBattStack->usDI4;	                       

	pNetBattStack->fStackVol = pBattStack->fStackVol;                   
	pNetBattStack->fStackCur = pBattStack->fStackCur;	                  
	pNetBattStack->fStackPower = pBattStack->fStackPower;                    
	pNetBattStack->fStackInsuRes = pBattStack->fStackInsuRes;                   
	pNetBattStack->fStackSoc = pBattStack->fStackSoc;                                      
	pNetBattStack->fStackSoh = pBattStack->fStackSoh;	                                       
	pNetBattStack->fStackChargeEQ = pBattStack->fStackChargeEQ;	               
	pNetBattStack->fStackDischargeEQ = pBattStack->fStackDischargeEQ;               
	pNetBattStack->fStackSglChargeEQ = pBattStack->fStackSglChargeEQ;             
	pNetBattStack->fStackSglDischargeEQ = pBattStack->fStackSglDischargeEQ;            
	pNetBattStack->fStackChargeEQAdd = (float)pBattStack->dblStackChargeEQAdd;           
	pNetBattStack->fStackDischargeEQAdd = (float)pBattStack->dblStackDischargeEQAdd;	       
	pNetBattStack->fStackSglChargeAh = pBattStack->fStackSglChargeAh;                          
	pNetBattStack->fStackSglDischargeAh = pBattStack->fStackSglDischargeAh;                    
	pNetBattStack->fStackChargeAhAdd = (float)pBattStack->dblStackChargeAhAdd;                        
	pNetBattStack->fStackDischargeAhAdd = (float)pBattStack->dblStackDischargeAhAdd;	       
	pNetBattStack->fSglVolDiffInStack = pBattStack->fSglVolDiffInStack;            
	pNetBattStack->fSglMaxVolInStack = pBattStack->fSglMaxVolInStack;             
	pNetBattStack->fSglMinVolInStack = pBattStack->fSglMinVolInStack;             
	pNetBattStack->fSglTempDiffInStack = pBattStack->fSglTempDiffInStack;            
	pNetBattStack->fSglMaxTempInStack = pBattStack->fSglMaxTempInStack;             
	pNetBattStack->fSglMinTempInStack = pBattStack->fSglMinTempInStack;             
	pNetBattStack->fBankSocDiff = pBattStack->fBankSocDiff;                   
	pNetBattStack->fBankSocMax = pBattStack->fBankSocMax;                   
	pNetBattStack->fBankSocMin = pBattStack->fBankSocMin;                  
	pNetBattStack->fBankVolDiff = pBattStack->fBankVolDiff;                
	pNetBattStack->fBankVolMax = pBattStack->fBankVolMax;                    
	pNetBattStack->fBankVolMin = pBattStack->fBankVolMin;                   
	pNetBattStack->fStackAllowMaxChargePower = pBattStack->fStackAllowMaxChargePower;       
	pNetBattStack->fStackAllowMaxDischargePower = pBattStack->fStackAllowMaxDischargePower;   
	pNetBattStack->fStackAllowMaxChargeCurrent = pBattStack->fStackAllowMaxChargeCurrent;     
	pNetBattStack->fStackAllowMaxDischargeCurrent = pBattStack->fStackAllowMaxDischargeCurrent;   

	// CRC 
	addCRC2Buffer((uchar *)pDataBuf, sizeof(SHeartbeat) + sizeof(SUpgHead) + sizeof(SNetBattStack));
	return sizeof(SHeartbeat) + sizeof(SUpgHead) + sizeof(SNetBattStack) + 2;
}

int CUpgFactory::prepareDatagramNotify(SHeartbeat* pHeartbeat, const QString& strUpdateInfo, char* pDataBuf)
{
	if (0 == pHeartbeat || 0 == pDataBuf || strUpdateInfo.isEmpty())
	{
		return -1;
	}

	// some variables Hearbeat Head Data CRC
	SUpgHead* pUpgHead = 0;

	if(sizeof(SHeartbeat) + sizeof(SUpgHead) + strUpdateInfo.length() + 1 + 2 /*CRC*/ > SNED_BUFFER_LENGHT)
	{
		return -2;
	}

	// Head
	memset(pDataBuf, 0, SNED_BUFFER_LENGHT);
	memcpy(pDataBuf, (char*)pHeartbeat, sizeof(SHeartbeat));

	pUpgHead = (SUpgHead*)(pDataBuf + sizeof(SHeartbeat));
	pUpgHead->uCmdType = UPG_MSG_NOTIFICATION;
	pUpgHead->uModbusAddrBg = 0xff;
	pUpgHead->usDataLen = strUpdateInfo.length() + 1;
	memcpy(pDataBuf + sizeof(SHeartbeat) + sizeof(SUpgHead), strUpdateInfo.toAscii().data(), strUpdateInfo.length());

	// CRC 
	addCRC2Buffer((uchar *)pDataBuf, sizeof(SHeartbeat) + sizeof(SUpgHead) + pUpgHead->usDataLen);
	return sizeof(SHeartbeat) + sizeof(SUpgHead) + pUpgHead->usDataLen + 2;
}

int CUpgFactory::prepareDatagramVersion(SHeartbeat* pHeartbeat, CBattStack* pBattStack, char* pDataBuf)
{
	if (0 == pHeartbeat || 0 == pBattStack || 0 == pDataBuf)
	{
		return -1;
	}

	// some variables Hearbeat Head Data CRC
	SUpgHead* pUpgHead = 0;
	SNetVersion* pNetVersion = 0;

	if(sizeof(SHeartbeat) + sizeof(SUpgHead) + sizeof(SNetVersion) + 2 /*CRC*/ > SNED_BUFFER_LENGHT)
	{
		return -2;
	}

	// Head
	memset(pDataBuf, 0, SNED_BUFFER_LENGHT);
	memcpy(pDataBuf, (char*)pHeartbeat, sizeof(SHeartbeat));

	pUpgHead = (SUpgHead*)(pDataBuf + sizeof(SHeartbeat));
	pNetVersion = (SNetVersion*)(pDataBuf + sizeof(SHeartbeat) + sizeof(SUpgHead));

	pUpgHead->uCmdType = UPG_DATA_VERSION;
	pUpgHead->uModbusAddrBg = 1;
	pUpgHead->usDataLen = sizeof(SNetVersion);

	// Data
	pNetVersion->usIP1 = 0;
	pNetVersion->usIP2 = 0;
	pNetVersion->usIP3 = 0;
	pNetVersion->usIP4 = 0;

	pNetVersion->usBaVers1 = BAMS_VERSION_MAJOR; 	
	pNetVersion->usBaVers2 = BAMS_VERSION_MINOR; 
	pNetVersion->usBaVers3 = BAMS_VERSION_REVISION; 
	pNetVersion->uaDacSrvVers = pBattStack->uaDacSrvVers;                   
	pNetVersion->uaDacAssVers = pBattStack->uaDacAssVers;                  
	pNetVersion->uaProcSrvVers = pBattStack->uaProcSrvVers;              
	pNetVersion->uaTranSrvVers = pBattStack->uaTranSrvVers;                   
	pNetVersion->uaViewVers = pBattStack->uaViewVers;                     
	pNetVersion->uaPlatVers = pBattStack->uaPlatVers;                     

	pNetVersion-> usBcVers1 = 0; 	
	pNetVersion-> usBcVers2 = 0; 
	pNetVersion-> usBcVers3 = 0; 
	pNetVersion-> usBcVers4 = 0; 
	pNetVersion-> usBmuVers1 = 0; 	
	pNetVersion-> usBmuVers2 = 0; 
	pNetVersion-> usBmuVers3 = 0; 
	pNetVersion-> usBmuVers4 = 0; 

	// CRC 
	addCRC2Buffer((uchar *)pDataBuf, sizeof(SHeartbeat) + sizeof(SUpgHead) + sizeof(SNetVersion));
	return sizeof(SHeartbeat) + sizeof(SUpgHead) + sizeof(SNetVersion) + 2;
}

// >= 0 OK 
// -1 参数错误 
//int CUpgFactory::prepareDatagramBAComInputReg(quint8 uaBAIndex, quint16* pComInputRegData, char* pDataBuf)
//{
//	if (0 == pComInputRegData || 0 == pDataBuf || uaBAIndex < 1)
//	{
//		return -1;
//	}
//
//	// some variables  Head Data CRC
//	int iLenVal = 0;	
//	SUpgHead* pUpgHead = 0;
//
//	// Head
//	pUpgHead = (SUpgHead*)(pDataBuf);
//
//	pUpgHead->uCmdType = UPG_DATA_BA_COM_INPUT_REG;
//	pUpgHead->uModbusAddrBg = uaBAIndex;
//	pUpgHead->usDataLen = 100 * 2;
//
//	// Data
//	memcpy((pDataBuf + sizeof(SUpgHead)), (char*)pComInputRegData, 100 * 2);
//
//	// CRC
//	addCRC2Buffer((uchar *)pDataBuf, sizeof(SUpgHead) + 100 * 2);
//
//	iLenVal = sizeof(SUpgHead) + 2 * 100 + 2;
//
//	return iLenVal;
//}

// >= 0 OK 
// -1 参数错误 
// -2 长度不足
// -3 未知的消息类型
int CUpgFactory::prepareDatagramCmd(quint16 usAreaCode, quint8  uStationNo, quint8  uTransmitNo, quint8 uCmdType, CBattBank* pBattBank, char* pDataBuf, quint8 uModbusAddr, const QString& strParam)
{
	if (0 == pDataBuf)
	{
		return -1;
	}

	// some variables  Head  Data  CRC
	int iLenVal = 0;	
	SHeartbeat* pHeartbeat = 0;
	SUpgHead* pUpgHead = 0;
	float* pFVal = 0;
	quint8 uFileName[64]; 

	memset(pDataBuf, 0, SNED_BUFFER_LENGHT);
	pHeartbeat = (SHeartbeat*)pDataBuf;
	pHeartbeat->usAreaCode = usAreaCode;
	pHeartbeat->uStationNo = uStationNo;
	pHeartbeat->uTransmitNo = uTransmitNo;

	pUpgHead = (SUpgHead*)(pDataBuf + sizeof(SHeartbeat));

	pUpgHead->uCmdType = uCmdType;
	pUpgHead->uModbusAddrBg = uModbusAddr;		

	switch (uCmdType)
	{
	case UPG_CMD_REBOOT:               // 远程重启
	case UPG_CMD_LAST_VERSION:         // 回退到上一版本

		pUpgHead->usDataLen = 4;		

		// CRC
		addCRC2Buffer((uchar *)pDataBuf, sizeof(SHeartbeat) + sizeof(SUpgHead) + 4);
		iLenVal = sizeof(SHeartbeat) + sizeof(SUpgHead) + 4 + 2;
		break;
	case UPG_CMD_SET_WARN_PARAM:       // 设置预警参数
	case UPG_CMD_SET_ALARM_PARAM:      // 设置告警参数
	case UPG_CMD_SET_PROT_PARAM:       // 设置保护参数
		if (pBattBank)
		{
			pUpgHead->usDataLen = 12 * 4;

			// Data
			pFVal = (float*)(pDataBuf + sizeof(SHeartbeat) + sizeof(SUpgHead));

			*pFVal = pBattBank->fCmdParam1; 
			++pFVal;
			*pFVal = pBattBank->fCmdParam2;
			++pFVal;
			*pFVal = pBattBank->fCmdParam3;
			++pFVal;
			*pFVal = pBattBank->fCmdParam4;
			++pFVal;
			*pFVal = pBattBank->fCmdParam5;
			++pFVal;
			*pFVal = pBattBank->fCmdParam6;
			++pFVal;
			*pFVal = pBattBank->fCmdParam7;
			++pFVal;
			*pFVal = pBattBank->fCmdParam8;
			++pFVal;
			*pFVal = pBattBank->fCmdParam9;
			++pFVal;
			*pFVal = pBattBank->fCmdParam10;
			++pFVal;
			*pFVal = pBattBank->fCmdParam11;
			++pFVal;
			*pFVal = pBattBank->fCmdParam12;
			++pFVal;

			// CRC
			addCRC2Buffer((uchar *)pDataBuf, sizeof(SHeartbeat) +  sizeof(SUpgHead) + 12 * 4);
			iLenVal =  sizeof(SHeartbeat) + sizeof(SUpgHead) + 4 * 12 + 2;
		}
		else
		{
			iLenVal = -1;
		}
		break;	
	case UPG_CMD_UPGRADE:            // 远程升级
		pUpgHead->usDataLen = strParam.length() + 1;
		memcpy(pDataBuf + sizeof(SHeartbeat) + sizeof(SUpgHead), strParam.toAscii().data(), strParam.length());

		// CRC
		addCRC2Buffer((uchar *)pDataBuf, sizeof(SHeartbeat) + sizeof(SUpgHead) + pUpgHead->usDataLen);
		iLenVal = sizeof(SHeartbeat) + sizeof(SUpgHead) + pUpgHead->usDataLen + 2;
		break;
	case UPG_CMD_POST_BACK_BA:       // 回传BA的版本
		break;
	default:
		iLenVal = -3;
		break;
	}

	return iLenVal;
}



// >= 0 OK 
// -1 参数错误 
// -2 长度不足
// -3 未知的消息类型
int CUpgFactory::prepareDatagramBank(SHeartbeat* pHeartbeat, quint8 uCmdType, CBattBank* pBattBank, CBankAlarm* pBattAlarm, char* pDataBuf, quint8 uModbusAddr)
{
	if (0 == pBattBank || 0 == pDataBuf || 0 == pBattAlarm)
	{
		return -1;
	}

	// some variables  Head Data CRC
	int iLenVal = 0;	
	SUpgHead* pUpgHead = 0;
	SNetBattBankAlarm* pNetBattBankAlarm = 0;
	SNetBattBankSglOther* pNetBattBankSglOther = 0;
	float* pFVal = 0;

	memset(pDataBuf, 0, SNED_BUFFER_LENGHT);

	switch (uCmdType)
	{
	case UPG_DATA_BANK_ALARM:       // 电池组数据 - 告警信息 
		if(sizeof(SHeartbeat) + sizeof(SUpgHead) + sizeof(SNetBattBankAlarm) + 2 /*CRC*/ > SNED_BUFFER_LENGHT)
		{
			iLenVal = -2;
		}
		else
		{
			// Head
			memcpy(pDataBuf, (char*)pHeartbeat, sizeof(SHeartbeat));

			pUpgHead = (SUpgHead*)(pDataBuf + sizeof(SHeartbeat));
			pNetBattBankAlarm = (SNetBattBankAlarm*)(pDataBuf + sizeof(SHeartbeat) + sizeof(SUpgHead));

			pUpgHead->uCmdType = UPG_DATA_BANK_ALARM;
			pUpgHead->uModbusAddrBg = uModbusAddr;
			pUpgHead->usDataLen = sizeof(SNetBattBankAlarm);

			// Data
			pNetBattBankAlarm->aBankVolUpLimitWarn = pBattBank->aBankVolUpLimitWarn;   
			pNetBattBankAlarm->aBankVolDownLimitWarn = pBattBank->aBankVolDownLimitWarn;     
			pNetBattBankAlarm->aChgCurUpLimitWarn = pBattBank->aChgCurUpLimitWarn;		
			pNetBattBankAlarm->aDchgCurUpLimitWarn = pBattBank->aDchgCurUpLimitWarn;		
			pNetBattBankAlarm->aSglVolUpLimitWarn = pBattBank->aSglVolUpLimitWarn;	    
			pNetBattBankAlarm->aSglVolDownLimitWarn = pBattBank->aSglVolDownLimitWarn;	  
			pNetBattBankAlarm->aChgTempUpLimitWarn = pBattBank->aChgTempUpLimitWarn;	    
			pNetBattBankAlarm->aChgTempDownLimitWarn = pBattBank->aChgTempDownLimitWarn;	    
			pNetBattBankAlarm->aDchgTempUpLimitWarn = pBattBank->aDchgTempUpLimitWarn;	    
			pNetBattBankAlarm->aDchgTempDownLimitWarn = pBattBank->aDchgTempDownLimitWarn;	
			pNetBattBankAlarm->aSglTempUpLimitWarn = pBattBank->aSglTempUpLimitWarn;	    
			pNetBattBankAlarm->aSglTempDownLimitWarn = pBattBank->aSglTempDownLimitWarn;	    
			pNetBattBankAlarm->aEnvTempUpLimitWarn = pBattBank->aEnvTempUpLimitWarn;		
			pNetBattBankAlarm->aEnvTempDownLimitWarn = pBattBank->aEnvTempDownLimitWarn;	   
			pNetBattBankAlarm->aPowerLineTempUpLimitWarn = pBattBank->aPowerLineTempUpLimitWarn;	 
			pNetBattBankAlarm->aBankSocUpLimitWarn = pBattBank->aBankSocUpLimitWarn;	    
			pNetBattBankAlarm->aBankSocDownLimitWarn = pBattBank->aBankSocDownLimitWarn;	    
			pNetBattBankAlarm->aPosResDownLimitWarn = pBattBank->aPosResDownLimitWarn;		
			pNetBattBankAlarm->aNegResDownLimitWarn = pBattBank->aNegResDownLimitWarn;		
			pNetBattBankAlarm->aPackVolDiffUpLimitWarn = pBattBank->aPackVolDiffUpLimitWarn;	
			pNetBattBankAlarm->aPackTempDiffUpLimitWarn = pBattBank->aPackTempDiffUpLimitWarn;	
			pNetBattBankAlarm->aBankVolUpLimitAlarm = pBattBank->aBankVolUpLimitAlarm;	   
			pNetBattBankAlarm->aBankVolDownLimitAlarm = pBattBank->aBankVolDownLimitAlarm;     
			pNetBattBankAlarm->aChgCurUpLimitAlarm = pBattBank->aChgCurUpLimitAlarm;		
			pNetBattBankAlarm->aDchgCurUpLimitAlarm = pBattBank->aDchgCurUpLimitAlarm;		
			pNetBattBankAlarm->aSglVolUpLimitAlarm = pBattBank->aSglVolUpLimitAlarm;	     
			pNetBattBankAlarm->aSglVolDownLimitAlarm = pBattBank->aSglVolDownLimitAlarm;	    
			pNetBattBankAlarm->aChgTempUpLimitAlarm = pBattBank->aChgTempUpLimitAlarm;	     
			pNetBattBankAlarm->aChgTempDownLimitAlarm = pBattBank->aChgTempDownLimitAlarm;	 
			pNetBattBankAlarm->aDchgTempUpLimitAlarm = pBattBank->aDchgTempUpLimitAlarm;	    
			pNetBattBankAlarm->aDchgTempDownLimitAlarm = pBattBank->aDchgTempDownLimitAlarm;	
			pNetBattBankAlarm->aSglTempUpLimitAlarm = pBattBank->aSglTempUpLimitAlarm;	     
			pNetBattBankAlarm->aSglTempDownLimitAlarm = pBattBank->aSglTempDownLimitAlarm;	
			pNetBattBankAlarm->aEnvTempUpLimitAlarm = pBattBank->aEnvTempUpLimitAlarm;		
			pNetBattBankAlarm->aEnvTempDownLimitAlarm = pBattBank->aEnvTempDownLimitAlarm;	
			pNetBattBankAlarm->aPowerLineTempUpLimitAlarm = pBattBank->aPowerLineTempUpLimitAlarm; 
			pNetBattBankAlarm->aBankSocUpLimitAlarm = pBattBank->aBankSocUpLimitAlarm;	    
			pNetBattBankAlarm->aBankSocDownLimitAlarm = pBattBank->aBankSocDownLimitAlarm;	
			pNetBattBankAlarm->aPosResDownLimitAlarm = pBattBank->aPosResDownLimitAlarm;		
			pNetBattBankAlarm->aNegResDownLimitAlarm = pBattBank->aNegResDownLimitAlarm;		
			pNetBattBankAlarm->aPackVolDiffUpLimitAlarm = pBattBank->aPackVolDiffUpLimitAlarm;	
			pNetBattBankAlarm->aPackTempDiffUpLimitAlarm = pBattBank->aPackTempDiffUpLimitAlarm;	
			pNetBattBankAlarm->aBankVolUpLimitProt = pBattBank->aBankVolUpLimitProt;	   
			pNetBattBankAlarm->aBankVolDownLimitProt = pBattBank->aBankVolDownLimitProt;     
			pNetBattBankAlarm->aChgCurUpLimitProt = pBattBank->aChgCurUpLimitProt;		 
			pNetBattBankAlarm->aDchgCurUpLimitProt = pBattBank->aDchgCurUpLimitProt;		
			pNetBattBankAlarm->aSglVolUpLimitProt = pBattBank->aSglVolUpLimitProt;	   
			pNetBattBankAlarm->aSglVolDownLimitProt = pBattBank->aSglVolDownLimitProt;	    
			pNetBattBankAlarm->aChgTempUpLimitProt = pBattBank->aChgTempUpLimitProt;	   	
			pNetBattBankAlarm->aChgTempDownLimitProt = pBattBank->aChgTempDownLimitProt;	    
			pNetBattBankAlarm->aDchgTempUpLimitProt = pBattBank->aDchgTempUpLimitProt;	     
			pNetBattBankAlarm->aDchgTempDownLimitProt = pBattBank->aDchgTempDownLimitProt;	
			pNetBattBankAlarm->aSglTempUpLimitProt = pBattBank->aSglTempUpLimitProt;	     
			pNetBattBankAlarm->aSglTempDownLimitProt = pBattBank->aSglTempDownLimitProt;	   
			pNetBattBankAlarm->aEnvTempUpLimitProt = pBattBank->aEnvTempUpLimitProt;		
			pNetBattBankAlarm->aEnvTempDownLimitProt = pBattBank->aEnvTempDownLimitProt;	  
			pNetBattBankAlarm->aPowerLineTempUpLimitProt = pBattBank->aPowerLineTempUpLimitProt;	 
			pNetBattBankAlarm->aBankSocUpLimitProt = pBattBank->aBankSocUpLimitProt;	    
			pNetBattBankAlarm->aBankSocDownLimitProt = pBattBank->aBankSocDownLimitProt;	     
			pNetBattBankAlarm->aPosResDownLimitProt = pBattBank->aPosResDownLimitProt;		
			pNetBattBankAlarm->aNegResDownLimitProt = pBattBank->aNegResDownLimitProt;		
			pNetBattBankAlarm->aPackVolDiffUpLimitProt = pBattBank->aPackVolDiffUpLimitProt;
			pNetBattBankAlarm->aPackTempDiffUpLimitProt = pBattBank->aPackTempDiffUpLimitProt;	
			pNetBattBankAlarm->aSglTempRise = pBattBank->aSglTempRise;	          
			pNetBattBankAlarm->aPowerLineTempRise = pBattBank->aPowerLineTempRise;	   
			pNetBattBankAlarm->aBMUConnFault = pBattBank->aBMUConnFault;		         
			pNetBattBankAlarm->aBCMUConnFault = pBattBank->aBCMUConnFault;		   
			pNetBattBankAlarm->aSglVolWireFault = pBattBank->aSglVolWireFault;        
			pNetBattBankAlarm->aBankVolWireFault = pBattBank->aBankVolWireFault;         
			pNetBattBankAlarm->aCurWireFault = pBattBank->aCurWireFault;            
			pNetBattBankAlarm->aTempWireBreak = pBattBank->aTempWireBreak;             
			pNetBattBankAlarm->aTempShortCircuit = pBattBank->aTempShortCircuit;          
			pNetBattBankAlarm->aBMSFault = pBattBank->aBMSFault;                 
			pNetBattBankAlarm->aSglVolInvalid = pBattBank->aSglVolInvalid;           
			pNetBattBankAlarm->aSglTempInvalid = pBattBank->aSglTempInvalid;           
			pNetBattBankAlarm->aBankVolInvalid = pBattBank->aBankVolInvalid;           

			// CRC
			addCRC2Buffer((uchar *)pDataBuf, sizeof(SHeartbeat) + sizeof(SUpgHead) + sizeof(SNetBattBankAlarm));
			iLenVal = sizeof(SHeartbeat) + sizeof(SUpgHead) + sizeof(SNetBattBankAlarm) + 2;
		}
		break;
	case UPG_DATA_BANK_SGL_VOL1:    // 单体电压   1 - 100
		if (pBattBank->usCellNumInBank > 1)
		{
			// Head
			memcpy(pDataBuf, (char*)pHeartbeat, sizeof(SHeartbeat));
			pUpgHead = (SUpgHead*)(pDataBuf + sizeof(SHeartbeat));

			pUpgHead->uCmdType = UPG_DATA_BANK_SGL_VOL1;
			pUpgHead->uModbusAddrBg = uModbusAddr;
			pUpgHead->usDataLen = 100 * 4;

			// Data
			memcpy((pDataBuf + sizeof(SHeartbeat) + sizeof(SUpgHead)), (char*)&(pBattBank->fSglVol[0]), 100 * 4);

			// CRC
			addCRC2Buffer((uchar *)pDataBuf, sizeof(SHeartbeat) + sizeof(SUpgHead) + 100 * 4);

			iLenVal = sizeof(SHeartbeat) + sizeof(SUpgHead) + 4 * 100 + 2;
		}		
		break;
	case UPG_DATA_BANK_SGL_VOL2:    // 单体电压 101 - 200
		if (pBattBank->usCellNumInBank > 100)
		{
			// Head
			memcpy(pDataBuf, (char*)pHeartbeat, sizeof(SHeartbeat));
			pUpgHead = (SUpgHead*)(pDataBuf + sizeof(SHeartbeat));

			pUpgHead->uCmdType = UPG_DATA_BANK_SGL_VOL2;
			pUpgHead->uModbusAddrBg = uModbusAddr;
			pUpgHead->usDataLen = 100 * 4;

			// Data
			memcpy((pDataBuf + sizeof(SHeartbeat) + sizeof(SUpgHead)), (char*)&(pBattBank->fSglVol[100]), 100 * 4);

			// CRC
			addCRC2Buffer((uchar *)pDataBuf, sizeof(SHeartbeat) + sizeof(SUpgHead) + 100 * 4);

			iLenVal = sizeof(SHeartbeat) + sizeof(SUpgHead) + 4 * 100 + 2;
		}
		break;
	case UPG_DATA_BANK_SGL_VOL3:    // 单体电压 201 - 300
		if (pBattBank->usCellNumInBank > 200)
		{
			// Head
			memcpy(pDataBuf, (char*)pHeartbeat, sizeof(SHeartbeat));
			pUpgHead = (SUpgHead*)(pDataBuf + sizeof(SHeartbeat));

			pUpgHead->uCmdType = UPG_DATA_BANK_SGL_VOL3;
			pUpgHead->uModbusAddrBg = uModbusAddr;
			pUpgHead->usDataLen = 100 * 4;

			// Data
			memcpy((pDataBuf + sizeof(SHeartbeat) + sizeof(SUpgHead)), (char*)&(pBattBank->fSglVol[200]), 100 * 4);

			// CRC
			addCRC2Buffer((uchar *)pDataBuf, sizeof(SHeartbeat) + sizeof(SUpgHead) + 100 * 4);

			iLenVal = sizeof(SHeartbeat) + sizeof(SUpgHead) + 4 * 100 + 2;
		}
		break;
	case UPG_DATA_BANK_SGL_VOL4:    // 单体电压 301 - 400
		if (pBattBank->usCellNumInBank > 300)
		{
			// Head
			memcpy(pDataBuf, (char*)pHeartbeat, sizeof(SHeartbeat));
			pUpgHead = (SUpgHead*)(pDataBuf + sizeof(SHeartbeat));

			pUpgHead->uCmdType = UPG_DATA_BANK_SGL_VOL4;
			pUpgHead->uModbusAddrBg = uModbusAddr;
			pUpgHead->usDataLen = 100 * 4;

			// Data
			memcpy((pDataBuf + sizeof(SHeartbeat) + sizeof(SUpgHead)), (char*)&(pBattBank->fSglVol[300]), 100 * 4);

			// CRC
			addCRC2Buffer((uchar *)pDataBuf, sizeof(SHeartbeat) + sizeof(SUpgHead) + 100 * 4);

			iLenVal = sizeof(SHeartbeat) + sizeof(SUpgHead) + 4 * 100 + 2;
		}
		break;
	case UPG_DATA_BANK_SGL_TEMP1:   // 单体温度   1 - 100
		if (pBattBank->usTempNumInBank > 1)
		{
			// Head
			memcpy(pDataBuf, (char*)pHeartbeat, sizeof(SHeartbeat));
			pUpgHead = (SUpgHead*)(pDataBuf + sizeof(SHeartbeat));

			pUpgHead->uCmdType = UPG_DATA_BANK_SGL_TEMP1;
			pUpgHead->uModbusAddrBg = uModbusAddr;
			pUpgHead->usDataLen = 100 * 4;

			// Data
			memcpy((pDataBuf + sizeof(SHeartbeat) + sizeof(SUpgHead)), (char*)&(pBattBank->fSglTemp[0]), 100 * 4);

			// CRC
			addCRC2Buffer((uchar *)pDataBuf, sizeof(SHeartbeat) + sizeof(SUpgHead) + 100 * 4);

			iLenVal = sizeof(SHeartbeat) + sizeof(SUpgHead) + 4 * 100 + 2;
		}
		break;
	case UPG_DATA_BANK_SGL_TEMP2:   // 单体温度 101 - 200
		if (pBattBank->usTempNumInBank > 100)
		{
			// Head
			memcpy(pDataBuf, (char*)pHeartbeat, sizeof(SHeartbeat));
			pUpgHead = (SUpgHead*)(pDataBuf + sizeof(SHeartbeat));

			pUpgHead->uCmdType = UPG_DATA_BANK_SGL_TEMP2;
			pUpgHead->uModbusAddrBg = uModbusAddr;
			pUpgHead->usDataLen = 100 * 4;

			// Data
			memcpy((pDataBuf + sizeof(SHeartbeat) +  sizeof(SUpgHead)), (char*)&(pBattBank->fSglTemp[100]), 100 * 4);

			// CRC
			addCRC2Buffer((uchar *)pDataBuf, sizeof(SHeartbeat) + sizeof(SUpgHead) + 100 * 4);

			iLenVal = sizeof(SHeartbeat) + sizeof(SUpgHead) + 4 * 100 + 2;
		}
		break;
	case UPG_DATA_BANK_SGL_TEMP3:   // 单体温度 201 - 300
		if (pBattBank->usTempNumInBank > 200)
		{
			// Head
			memcpy(pDataBuf, (char*)pHeartbeat, sizeof(SHeartbeat));
			pUpgHead = (SUpgHead*)(pDataBuf + sizeof(SHeartbeat));

			pUpgHead->uCmdType = UPG_DATA_BANK_SGL_TEMP3;
			pUpgHead->uModbusAddrBg = uModbusAddr;
			pUpgHead->usDataLen = 100 * 4;

			// Data
			memcpy((pDataBuf + sizeof(SHeartbeat) +  sizeof(SUpgHead)), (char*)&(pBattBank->fSglTemp[200]), 100 * 4);

			// CRC
			addCRC2Buffer((uchar *)pDataBuf, sizeof(SHeartbeat) + sizeof(SUpgHead) + 100 * 4);

			iLenVal = sizeof(SHeartbeat) + sizeof(SUpgHead) + 4 * 100 + 2;
		}
		break;
	case UPG_DATA_BANK_SGL_TEMP4:   // 单体温度 301 - 400
		if (pBattBank->usTempNumInBank > 300)
		{
			// Head
			memcpy(pDataBuf, (char*)pHeartbeat, sizeof(SHeartbeat));
			pUpgHead = (SUpgHead*)(pDataBuf + sizeof(SHeartbeat));

			pUpgHead->uCmdType = UPG_DATA_BANK_SGL_TEMP4;
			pUpgHead->uModbusAddrBg = uModbusAddr;
			pUpgHead->usDataLen = 100 * 4;

			// Data
			memcpy((pDataBuf + sizeof(SHeartbeat) + sizeof(SUpgHead)), (char*)&(pBattBank->fSglTemp[300]), 100 * 4);

			// CRC
			addCRC2Buffer((uchar *)pDataBuf, sizeof(SHeartbeat) + sizeof(SUpgHead) + 100 * 4);

			iLenVal = sizeof(SHeartbeat) + sizeof(SUpgHead) + 4 * 100 + 2;
		}
		break;
	case UPG_DATA_BANK_SGL_SOC1:    // 单体Soc   1 - 100
		if (pBattBank->usCellNumInBank > 1)
		{
			// Head
			memcpy(pDataBuf, (char*)pHeartbeat, sizeof(SHeartbeat));
			pUpgHead = (SUpgHead*)(pDataBuf + sizeof(SHeartbeat));

			pUpgHead->uCmdType = UPG_DATA_BANK_SGL_SOC1;
			pUpgHead->uModbusAddrBg = uModbusAddr;
			pUpgHead->usDataLen = 100 * 4;

			// Data
			memcpy((pDataBuf + sizeof(SHeartbeat) + sizeof(SUpgHead)), (char*)&(pBattBank->fSglSoc[0]), 100 * 4);

			// CRC
			addCRC2Buffer((uchar *)pDataBuf, sizeof(SHeartbeat) + sizeof(SUpgHead) + 100 * 4);

			iLenVal = sizeof(SHeartbeat) + sizeof(SUpgHead) + 4 * 100 + 2;
		}
		break;
	case UPG_DATA_BANK_SGL_SOC2:    // 单体Soc 101 - 200
		if (pBattBank->usCellNumInBank > 100)
		{
			// Head
			memcpy(pDataBuf, (char*)pHeartbeat, sizeof(SHeartbeat));
			pUpgHead = (SUpgHead*)(pDataBuf + sizeof(SHeartbeat));

			pUpgHead->uCmdType = UPG_DATA_BANK_SGL_SOC2;
			pUpgHead->uModbusAddrBg = uModbusAddr;
			pUpgHead->usDataLen = 100 * 4;

			// Data
			memcpy((pDataBuf + sizeof(SHeartbeat) + sizeof(SUpgHead)), (char*)&(pBattBank->fSglSoc[100]), 100 * 4);

			// CRC
			addCRC2Buffer((uchar *)pDataBuf, sizeof(SHeartbeat) + sizeof(SUpgHead) + 100 * 4);

			iLenVal = sizeof(SHeartbeat) + sizeof(SUpgHead) + 4 * 100 + 2;
		}
		break;

	case UPG_DATA_BANK_SGL_SOC3:    // 单体Soc 201 - 300
		if (pBattBank->usCellNumInBank > 200)
		{
			// Head
			memcpy(pDataBuf, (char*)pHeartbeat, sizeof(SHeartbeat));
			pUpgHead = (SUpgHead*)(pDataBuf + sizeof(SHeartbeat));

			pUpgHead->uCmdType = UPG_DATA_BANK_SGL_SOC3;
			pUpgHead->uModbusAddrBg = uModbusAddr;
			pUpgHead->usDataLen = 100 * 4;

			// Data
			memcpy((pDataBuf + sizeof(SHeartbeat) + sizeof(SUpgHead)), (char*)&(pBattBank->fSglSoc[200]), 100 * 4);

			// CRC
			addCRC2Buffer((uchar *)pDataBuf, sizeof(SHeartbeat) + sizeof(SUpgHead) + 100 * 4);

			iLenVal = sizeof(SHeartbeat) + sizeof(SUpgHead) + 4 * 100 + 2;
		}
		break;
	case UPG_DATA_BANK_SGL_SOC4:    // 单体Soc 301 - 400
		if (pBattBank->usCellNumInBank > 300)
		{
			// Head
			memcpy(pDataBuf, (char*)pHeartbeat, sizeof(SHeartbeat));
			pUpgHead = (SUpgHead*)(pDataBuf + sizeof(SHeartbeat));

			pUpgHead->uCmdType = UPG_DATA_BANK_SGL_SOC4;
			pUpgHead->uModbusAddrBg = uModbusAddr;
			pUpgHead->usDataLen = 100 * 4;

			// Data
			memcpy((pDataBuf + sizeof(SHeartbeat) + sizeof(SUpgHead)), (char*)&(pBattBank->fSglSoc[300]), 100 * 4);

			// CRC
			addCRC2Buffer((uchar *)pDataBuf, sizeof(SHeartbeat) + sizeof(SUpgHead) + 100 * 4);

			iLenVal = sizeof(SHeartbeat) + sizeof(SUpgHead) + 4 * 100 + 2;
		}
		break;
	case UPG_DATA_BANK_SGL_RES1:    // 单体内阻   1 - 100
		if (pBattBank->usCellNumInBank > 1)
		{
			// Head
			memcpy(pDataBuf, (char*)pHeartbeat, sizeof(SHeartbeat));
			pUpgHead = (SUpgHead*)(pDataBuf + sizeof(SHeartbeat));

			pUpgHead->uCmdType = UPG_DATA_BANK_SGL_RES1;
			pUpgHead->uModbusAddrBg = uModbusAddr;
			pUpgHead->usDataLen = 100 * 4;

			// Data
			memcpy((pDataBuf + sizeof(SHeartbeat) + sizeof(SUpgHead)), (char*)&(pBattBank->fSglRes[0]), 100 * 4);

			// CRC
			addCRC2Buffer((uchar *)pDataBuf, sizeof(SHeartbeat) + sizeof(SUpgHead) + 100 * 4);

			iLenVal = sizeof(SHeartbeat) + sizeof(SUpgHead) + 4 * 100 + 2;
		}
		break;
	case UPG_DATA_BANK_SGL_RES2:    // 单体内阻 101 - 200
		if (pBattBank->usCellNumInBank > 100)
		{
			// Head
			memcpy(pDataBuf, (char*)pHeartbeat, sizeof(SHeartbeat));
			pUpgHead = (SUpgHead*)(pDataBuf + sizeof(SHeartbeat));

			pUpgHead->uCmdType = UPG_DATA_BANK_SGL_RES2;
			pUpgHead->uModbusAddrBg = uModbusAddr;
			pUpgHead->usDataLen = 100 * 4;

			// Data
			memcpy((pDataBuf + sizeof(SHeartbeat) + sizeof(SUpgHead)), (char*)&(pBattBank->fSglRes[100]), 100 * 4);

			// CRC
			addCRC2Buffer((uchar *)pDataBuf, sizeof(SHeartbeat) + sizeof(SUpgHead) + 100 * 4);

			iLenVal = sizeof(SHeartbeat) + sizeof(SUpgHead) + 4 * 100 + 2;
		}
		break;
	case UPG_DATA_BANK_SGL_RES3:    // 单体内阻 201 - 300
		if (pBattBank->usCellNumInBank > 200)
		{
			// Head
			memcpy(pDataBuf, (char*)pHeartbeat, sizeof(SHeartbeat));
			pUpgHead = (SUpgHead*)(pDataBuf + sizeof(SHeartbeat));

			pUpgHead->uCmdType = UPG_DATA_BANK_SGL_RES3;
			pUpgHead->uModbusAddrBg = uModbusAddr;
			pUpgHead->usDataLen = 100 * 4;

			// Data
			memcpy((pDataBuf + sizeof(SHeartbeat) + sizeof(SUpgHead)), (char*)&(pBattBank->fSglRes[200]), 100 * 4);

			// CRC
			addCRC2Buffer((uchar *)pDataBuf, sizeof(SHeartbeat) + sizeof(SUpgHead) + 100 * 4);

			iLenVal = sizeof(SHeartbeat) + sizeof(SUpgHead) + 4 * 100 + 2;
		}
		break;
	case UPG_DATA_BANK_SGL_RES4:    // 单体内阻 301 - 400
		if (pBattBank->usCellNumInBank > 300)
		{
			// Head
			memcpy(pDataBuf, (char*)pHeartbeat, sizeof(SHeartbeat));
			pUpgHead = (SUpgHead*)(pDataBuf + sizeof(SHeartbeat));

			pUpgHead->uCmdType = UPG_DATA_BANK_SGL_RES4;
			pUpgHead->uModbusAddrBg = uModbusAddr;
			pUpgHead->usDataLen = 100 * 4;

			// Data
			memcpy((pDataBuf + sizeof(SUpgHead)), (char*)&(pBattBank->fSglRes[300]), 100 * 4);

			// CRC
			addCRC2Buffer((uchar *)pDataBuf, sizeof(SHeartbeat) + sizeof(SUpgHead) + 100 * 4);

			iLenVal = sizeof(SHeartbeat) + sizeof(SUpgHead) + 4 * 100 + 2;
		}
		break;
	case UPG_DATA_BANK_SGL_SOH1:    // 单体Soh   1 - 100
		if (pBattBank->usCellNumInBank > 1)
		{
			// Head
			memcpy(pDataBuf, (char*)pHeartbeat, sizeof(SHeartbeat));
			pUpgHead = (SUpgHead*)(pDataBuf + sizeof(SHeartbeat));

			pUpgHead->uCmdType = UPG_DATA_BANK_SGL_SOH1;
			pUpgHead->uModbusAddrBg = uModbusAddr;
			pUpgHead->usDataLen = 100 * 4;

			// Data
			memcpy((pDataBuf + sizeof(SHeartbeat) + sizeof(SUpgHead)), (char*)&(pBattBank->fSglSoh[0]), 100 * 4);

			// CRC
			addCRC2Buffer((uchar *)pDataBuf, sizeof(SHeartbeat) + sizeof(SUpgHead) + 100 * 4);

			iLenVal = sizeof(SHeartbeat) + sizeof(SUpgHead) + 4 * 100 + 2;
		}
		break;
	case UPG_DATA_BANK_SGL_SOH2:    // 单体Soh 101 - 200
		if (pBattBank->usCellNumInBank > 100)
		{
			// Head
			memcpy(pDataBuf, (char*)pHeartbeat, sizeof(SHeartbeat));
			pUpgHead = (SUpgHead*)(pDataBuf + sizeof(SHeartbeat));

			pUpgHead->uCmdType = UPG_DATA_BANK_SGL_SOH2;
			pUpgHead->uModbusAddrBg = uModbusAddr;
			pUpgHead->usDataLen = 100 * 4;

			// Data
			memcpy((pDataBuf + sizeof(SHeartbeat) + sizeof(SUpgHead)), (char*)&(pBattBank->fSglSoh[100]), 100 * 4);

			// CRC
			addCRC2Buffer((uchar *)pDataBuf, sizeof(SHeartbeat) + sizeof(SUpgHead) + 100 * 4);

			iLenVal = sizeof(SHeartbeat) + sizeof(SUpgHead) + 4 * 100 + 2;
		}
		break;
	case UPG_DATA_BANK_SGL_SOH3:    // 单体Soh 201 - 300
		if (pBattBank->usCellNumInBank > 200)
		{
			// Head
			memcpy(pDataBuf, (char*)pHeartbeat, sizeof(SHeartbeat));
			pUpgHead = (SUpgHead*)(pDataBuf + sizeof(SHeartbeat));

			pUpgHead->uCmdType = UPG_DATA_BANK_SGL_SOH3;
			pUpgHead->uModbusAddrBg = uModbusAddr;
			pUpgHead->usDataLen = 100 * 4;

			// Data
			memcpy((pDataBuf + sizeof(SHeartbeat) +  sizeof(SUpgHead)), (char*)&(pBattBank->fSglSoh[200]), 100 * 4);

			// CRC
			addCRC2Buffer((uchar *)pDataBuf, sizeof(SHeartbeat) + sizeof(SUpgHead) + 100 * 4);

			iLenVal = sizeof(SHeartbeat) + sizeof(SUpgHead) + 4 * 100 + 2;
		}
		break;
	case UPG_DATA_BANK_SGL_SOH4:    // 单体Soh 301 - 400
		if (pBattBank->usCellNumInBank > 300)
		{
			// Head
			memcpy(pDataBuf, (char*)pHeartbeat, sizeof(SHeartbeat));
			pUpgHead = (SUpgHead*)(pDataBuf + sizeof(SHeartbeat));

			pUpgHead->uCmdType = UPG_DATA_BANK_SGL_SOH4;
			pUpgHead->uModbusAddrBg = uModbusAddr;
			pUpgHead->usDataLen = 100 * 4;

			// Data
			memcpy((pDataBuf + sizeof(SHeartbeat) + sizeof(SUpgHead)), (char*)&(pBattBank->fSglSoh[300]), 100 * 4);

			// CRC
			addCRC2Buffer((uchar *)pDataBuf, sizeof(SHeartbeat) + sizeof(SUpgHead) + 100 * 4);

			iLenVal = sizeof(SHeartbeat) + sizeof(SUpgHead) + 4 * 100 + 2;
		}
		break;
	case UPG_DATA_BANK_OTHER:       // 其他电池组数据
		if(sizeof(SHeartbeat) + sizeof(SUpgHead) + sizeof(SNetBattBankSglOther) + 2 /*CRC*/ > SNED_BUFFER_LENGHT)
		{
			iLenVal = -2;
		}
		else
		{
			// Head
			memcpy(pDataBuf, (char*)pHeartbeat, sizeof(SHeartbeat));
			pUpgHead = (SUpgHead*)(pDataBuf + sizeof(SHeartbeat));

			pNetBattBankSglOther = (SNetBattBankSglOther*)(pDataBuf + sizeof(SHeartbeat) + sizeof(SUpgHead));

			pUpgHead->uCmdType = UPG_DATA_BANK_OTHER;
			pUpgHead->uModbusAddrBg = uModbusAddr;
			pUpgHead->usDataLen = sizeof(SNetBattBankSglOther);

			// Data
			pNetBattBankSglOther->usBankState = pBattBank->usBankState;          
			pNetBattBankSglOther->usBankChgDchgState = pBattBank->usBankChgDchgState;	
			pNetBattBankSglOther->usCellNumInBank = pBattBank->usCellNumInBank;       
			pNetBattBankSglOther->usTempNumInBank = pBattBank->usTempNumInBank;      
			pNetBattBankSglOther->usPackNumInBank = pBattBank->usPackNumInBank;        
			pNetBattBankSglOther->usChgNum = pBattBank->usChgNum;	           
			pNetBattBankSglOther->usDchgNum = pBattBank->usDchgNum;	            
			pNetBattBankSglOther->usSglMaxVolNo = pBattBank->usSglMaxVolNo;        
			pNetBattBankSglOther->usSglMinVolNo = pBattBank->usSglMinVolNo;         
			pNetBattBankSglOther->usSglMaxTempNo = pBattBank->usSglMaxTempNo;      
			pNetBattBankSglOther->usSglMinTempNo = pBattBank->usSglMinTempNo;         
			pNetBattBankSglOther->usSglMaxResNo = pBattBank->usSglMaxResNo;       
			pNetBattBankSglOther->usSglMinResNo = pBattBank->usSglMinResNo;        
			pNetBattBankSglOther->usSglMaxSocNo = pBattBank->usSglMaxSocNo;          
			pNetBattBankSglOther->usSglMinSocNo = pBattBank->usSglMinSocNo;       
			pNetBattBankSglOther->usSglMaxSohNo = pBattBank->usSglMaxSohNo;        
			pNetBattBankSglOther->usSglMinSohNo = pBattBank->usSglMinSohNo;       	
			pNetBattBankSglOther->usDI1 = pBattBank->usDI1;   			
			pNetBattBankSglOther->usDI2 = pBattBank->usDI2;	                
			pNetBattBankSglOther->usDI3 = pBattBank->usDI3;	                
			pNetBattBankSglOther->usDI4 = pBattBank->usDI4;	               
			pNetBattBankSglOther->usDI5 = pBattBank->usDI5;	               
			pNetBattBankSglOther->usDI6 = pBattBank->usDI6;	                

			pNetBattBankSglOther->fBankVol = pBattBank->fBankVol;	           
			pNetBattBankSglOther->fBankCur = pBattBank->fBankCur;	           
			pNetBattBankSglOther->fBankPower = pBattBank->fBankPower;              
			pNetBattBankSglOther->fBankInsuRes = pBattBank->fBankInsuRes;            
			pNetBattBankSglOther->fBankSoc = pBattBank->fBankSoc;              
			pNetBattBankSglOther->fBankSoh = pBattBank->fBankSoh;             
			pNetBattBankSglOther->fEnvTemp = pBattBank->fEnvTemp;	          
			pNetBattBankSglOther->fPosRes = pBattBank->fPosRes;	              
			pNetBattBankSglOther->fNegRes = pBattBank->fNegRes;                 
			pNetBattBankSglOther->fBankChargeEQ = pBattBank->fBankChargeEQ;	        
			pNetBattBankSglOther->fBankDischargeEQ = pBattBank->fBankDischargeEQ;	   
			pNetBattBankSglOther->fBankSglChargeEQ = pBattBank->fBankSglChargeEQ;    	
			pNetBattBankSglOther->fBankSglDischargeEQ = pBattBank->fBankSglDischargeEQ;	   
			pNetBattBankSglOther->fBankChargeEQAdd = pBattBank->dblBankChargeEQAdd;	   
			pNetBattBankSglOther->fBankDischargeEQAdd = pBattBank->dblBankDischargeEQAdd;    
			pNetBattBankSglOther->fBankSglChargeAh = pBattBank->fBankSglChargeAh;    	   
			pNetBattBankSglOther->fBankSglDischargeAh = pBattBank->fBankSglDischargeAh;	  
			pNetBattBankSglOther->fBankChargeAhAdd = pBattBank->dblBankChargeAhAdd;	     	           
			pNetBattBankSglOther->fBankDischargeAhAdd = pBattBank->dblBankDischargeAhAdd;             
			pNetBattBankSglOther->fSglVolDiffInBank = pBattBank->fSglVolDiffInBank;        
			pNetBattBankSglOther->fSglAvgVol = pBattBank->fSglAvgVol;             
			pNetBattBankSglOther->fSglMaxVol = pBattBank->fSglMaxVol;              
			pNetBattBankSglOther->fSglMinVol = pBattBank->fSglMinVol;	            
			pNetBattBankSglOther->fSglTempDiffInBank = pBattBank->fSglTempDiffInBank;      		
			pNetBattBankSglOther->fSglAvgTemp = pBattBank->fSglAvgTemp;	            
			pNetBattBankSglOther->fSglMaxTemp = pBattBank->fSglMaxTemp;              	
			pNetBattBankSglOther->fSglMinTemp = pBattBank->fSglMinTemp;             	
			pNetBattBankSglOther->fSglAvgRes = pBattBank->fSglAvgRes;               
			pNetBattBankSglOther->fSglMaxRes = pBattBank->fSglMaxRes;              
			pNetBattBankSglOther->fSglMinRes = pBattBank->fSglMinRes;             
			pNetBattBankSglOther->fSglAvgSoc = pBattBank->fSglAvgSoc;	           
			pNetBattBankSglOther->fSglMaxSoc = pBattBank->fSglMaxSoc;           
			pNetBattBankSglOther->fSglMinSoc = pBattBank->fSglMinSoc;              	
			pNetBattBankSglOther->fSglAvgSoh = pBattBank->fSglAvgSoh;              
			pNetBattBankSglOther->fSglMaxSoh = pBattBank->fSglMaxSoh;             
			pNetBattBankSglOther->fSglMinSoh = pBattBank->fSglMinSoh;              	
			pNetBattBankSglOther->fBankAllowMaxChargePower = pBattBank->fBankAllowMaxChargePower;    
			pNetBattBankSglOther->fBankAllowMaxDischargePower = pBattBank->fBankAllowMaxDischargePower;  
			pNetBattBankSglOther->fBankAllowMaxChargeCurrent = pBattBank->fBankAllowMaxChargeCurrent;    
			pNetBattBankSglOther->fBankAllowMaxDischargeCurrent = pBattBank->fBankAllowMaxDischargeCurrent;                     
			
			// CRC
			addCRC2Buffer((uchar *)pDataBuf, sizeof(SHeartbeat) + sizeof(SUpgHead) + sizeof(SNetBattBankSglOther));

			iLenVal = sizeof(SHeartbeat) + sizeof(SUpgHead) + sizeof(SNetBattBankSglOther) + 2;
		}
		break;

	case UPG_DATA_WARN_PARAM:    // 预警参数  		
		// Head
		memcpy(pDataBuf, (char*)pHeartbeat, sizeof(SHeartbeat));
		pUpgHead = (SUpgHead*)(pDataBuf + sizeof(SHeartbeat));

		pUpgHead->uCmdType = UPG_DATA_WARN_PARAM;
		pUpgHead->uModbusAddrBg = uModbusAddr;
		pUpgHead->usDataLen = 12 * 4;

		// Data
		pFVal = (float*)(pDataBuf + sizeof(SHeartbeat) + sizeof(SUpgHead));

		*pFVal = pBattAlarm->param.fBankVolUpLimitWarn;
		++pFVal;
		*pFVal = pBattAlarm->param.fBankVolDownLimitWarn;
		++pFVal;
		*pFVal = pBattAlarm->param.fChargeCurUpLimitWarn;
		++pFVal;
		*pFVal = pBattAlarm->param.fDischargeCurUpLimitWarn;
		++pFVal;
		*pFVal = pBattAlarm->param.fSglVolUpLimitWarn;
		++pFVal;
		*pFVal = pBattAlarm->param.fSglVolDownLimitWarn;
		++pFVal;
		*pFVal = pBattAlarm->param.fChargeSglTempUpLimitWarn;
		++pFVal;
		*pFVal = pBattAlarm->param.fChargeSglTempDownLimitWarn;
		++pFVal;
		*pFVal = pBattAlarm->param.fDchargeSglTempUpLimitWarn;
		++pFVal;
		*pFVal = pBattAlarm->param.fDchargeSglTempDownLimitWarn;
		++pFVal;
		*pFVal = pBattAlarm->param.fBankSocUpLimitWarn;
		++pFVal;
		*pFVal = pBattAlarm->param.fBankSocDownLimitWarn;
		++pFVal;

		// CRC
		addCRC2Buffer((uchar *)pDataBuf, sizeof(SHeartbeat) + sizeof(SUpgHead) + 12 * 4);
		iLenVal = sizeof(SHeartbeat) + sizeof(SUpgHead) + 4 * 12 + 2;
		break;
	case UPG_DATA_ALARM_PARAM:    // 告警参数  		
		// Head
		memcpy(pDataBuf, (char*)pHeartbeat, sizeof(SHeartbeat));
		pUpgHead = (SUpgHead*)(pDataBuf + sizeof(SHeartbeat));


		pUpgHead->uCmdType = UPG_DATA_ALARM_PARAM;
		pUpgHead->uModbusAddrBg = uModbusAddr;
		pUpgHead->usDataLen = 12 * 4;

		// Data
		pFVal = (float*)(pDataBuf + sizeof(SHeartbeat) + sizeof(SUpgHead));

		*pFVal = pBattAlarm->param.fBankVolUpLimitAlarm;
		++pFVal;
		*pFVal = pBattAlarm->param.fBankVolDownLimitAlarm;
		++pFVal;
		*pFVal = pBattAlarm->param.fChargeCurUpLimitAlarm;
		++pFVal;
		*pFVal = pBattAlarm->param.fDischargeCurUpLimitAlarm;
		++pFVal;
		*pFVal = pBattAlarm->param.fSglVolUpLimitAlarm;
		++pFVal;
		*pFVal = pBattAlarm->param.fSglVolDownLimitAlarm;
		++pFVal;
		*pFVal = pBattAlarm->param.fChargeSglTempUpLimitAlarm;
		++pFVal;
		*pFVal = pBattAlarm->param.fChargeSglTempDownLimitAlarm;
		++pFVal;
		*pFVal = pBattAlarm->param.fDchargeSglTempUpLimitAlarm;
		++pFVal;
		*pFVal = pBattAlarm->param.fDchargeSglTempDownLimitAlarm;
		++pFVal;
		*pFVal = pBattAlarm->param.fBankSocUpLimitAlarm;
		++pFVal;
		*pFVal = pBattAlarm->param.fBankSocDownLimitAlarm;
		++pFVal;
		// CRC
		addCRC2Buffer((uchar *)pDataBuf, sizeof(SHeartbeat) + sizeof(SUpgHead) + 12 * 4);
		iLenVal = sizeof(SHeartbeat) + sizeof(SUpgHead) + 4 * 12 + 2;
		break;
	case UPG_DATA_PROT_PARAM:    // 保护参数  		
		// Head
		memcpy(pDataBuf, (char*)pHeartbeat, sizeof(SHeartbeat));
		pUpgHead = (SUpgHead*)(pDataBuf + sizeof(SHeartbeat));

		pUpgHead->uCmdType = UPG_DATA_PROT_PARAM;
		pUpgHead->uModbusAddrBg = uModbusAddr;
		pUpgHead->usDataLen = 12 * 4;

		// Data
		pFVal = (float*)(pDataBuf + sizeof(SHeartbeat) + sizeof(SUpgHead));
		*pFVal = pBattAlarm->param.fBankVolUpLimitProt;
		++pFVal;
		*pFVal = pBattAlarm->param.fBankVolDownLimitProt;
		++pFVal;
		*pFVal = pBattAlarm->param.fChargeCurUpLimitProt;
		++pFVal;
		*pFVal = pBattAlarm->param.fDischargeCurUpLimitProt;
		++pFVal;
		*pFVal = pBattAlarm->param.fSglVolUpLimitProt;
		++pFVal;
		*pFVal = pBattAlarm->param.fSglVolDownLimitProt;
		++pFVal;
		*pFVal = pBattAlarm->param.fChargeSglTempUpLimitProt;
		++pFVal;
		*pFVal = pBattAlarm->param.fChargeSglTempDownLimitProt;
		++pFVal;
		*pFVal = pBattAlarm->param.fDchargeSglTempUpLimitProt;
		++pFVal;
		*pFVal = pBattAlarm->param.fDchargeSglTempDownLimitProt;
		++pFVal;
		*pFVal = pBattAlarm->param.fBankSocUpLimitProt;
		++pFVal;
		*pFVal = pBattAlarm->param.fBankSocDownLimitProt;
		++pFVal;	

		// CRC
		addCRC2Buffer((uchar *)pDataBuf, sizeof(SHeartbeat) + sizeof(SUpgHead) + 12 * 4);
		iLenVal = sizeof(SHeartbeat) + sizeof(SUpgHead) + 4 * 12 + 2;			
		break;
	default:
		iLenVal = -3;
		break;
	}

	return iLenVal;
}

int CUpgFactory::addParam2Buffer(char* pData, quint32 uiParamVal)
{
	*pData = (char)(uiParamVal >> 24);

	++pData;
	*pData = (char)(uiParamVal >> 16);

	++pData;
	*pData = (char)(uiParamVal >> 8);

	++pData;
	*pData = (char)(uiParamVal);

	return  0;
}

int CUpgFactory::addParam2Buffer(char* pData, quint16 uiParamVal)
{
	*pData = (char)(uiParamVal >> 8);

	++pData;
	*pData = (char)(uiParamVal);

	return  0;
}

int CUpgFactory::addParam2Buffer(char* pData, float fParamVal)
{
	char aTemp[4];
	memcpy(aTemp, &fParamVal, 4);

	*pData = aTemp[3];
	++pData;
	*pData = aTemp[2];
	++pData;
	*pData = aTemp[1];
	++pData;
	*pData = aTemp[0];

	return 0;
}

int CUpgFactory::getParamFromBuffer(char* pData, quint16& uiParamVal)
{
	uiParamVal = (unsigned char)*pData;
	uiParamVal = uiParamVal * 256;

	++pData;

	uiParamVal += (unsigned char)*pData;

	return 0;
}

int CUpgFactory::getParamFromBuffer(char* pData, quint32& uiParamVal)
{
	uiParamVal = (unsigned char)*pData;

	uiParamVal = uiParamVal * 256;
	++pData;
	uiParamVal += (unsigned char)*pData;

	uiParamVal = uiParamVal * 256;
	++pData;
	uiParamVal += (unsigned char)*pData;

	uiParamVal = uiParamVal * 256;
	++pData;
	uiParamVal += (unsigned char)*pData;

	return 0;
}


int CUpgFactory::getParamFromBuffer(char* pData, float& fParamVal)
{
	char aTemp[4];
	aTemp[3] = *pData;
	++pData;
	aTemp[2] = *pData;
	++pData;
	aTemp[1] = *pData;
	++pData;
	aTemp[0] = *pData;

	memcpy(&fParamVal, aTemp, 4);
	return 0;
}

int CUpgFactory::addCRC2Buffer(uchar *pData, int iLen)
{
	quint16 usCRC = CRC16(pData, iLen);

	return addParam2Buffer((char*)(pData + iLen), usCRC);
}

// 计算CRC校验
//********************************************************************
// FUCTION: CRC16 —— CRC16校验生成函数
// VERSION: 1	(2010-9-27 14:34:01)
// INPUT:	dat_buf 待校验数值缓存区
// 			dat_len 待校验数值缓存区的长度
// OUTPUT:	CRC16校验值
// EXAMPLE:
// 输入数据 dat_buf指向的数组为： 0x33, 0x78, 0x98, 0x60, 校验长度为4
// 则输出为：高字节0x3B 低字节0x78
// NOTE：	参考技术标准文件《CRC校验原理》		
//********************************************************************
quint16 CUpgFactory::CRC16(uchar *dat_buf, quint16 dat_len)
{
	uchar j, r1, r2, r3, r4;
	quint16 i;
	
	r1 = dat_buf[0];
	r2 = dat_buf[1];

	for (i = 2; i < dat_len + 2; i++)
	{
		if (i < dat_len)
		{
			r3 = dat_buf[i];		
		}
		else
		{
			r3 = 0;
		}

		for (j = 0; j < 8; j++)
		{
			r4 = r1;
			r1 = (r1 << 1);
			if ((r2 & 0x80) != 0) r1++;
			r2 = r2 << 1;
			if ((r3 & 0x80) != 0) r2++;
			r3 = (r3 << 1);
			if ((r4 & 0x80) != 0)
			{
				r1 = r1 ^ 0x10;
				r2 = r2 ^ 0x21;
			}
		}
	}
	return (r1 * 0x100 + r2);
}

